logstash-output-qingstor 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7edeee9f910f1ff39de1856a36166c30ad66052e
4
- data.tar.gz: 31b21ceee52a6402f89fa782f368450e1f84ebd4
3
+ metadata.gz: d1fb6b25a4999d3628887cb326a791afddb002dd
4
+ data.tar.gz: d72aca418dc34fe47c11f303c7f48e459a35715c
5
5
  SHA512:
6
- metadata.gz: 088f7febcb4b81f11d956c52dc5aa100e01eb7cd4d50670952b9f24ac2b54f24447b17a74900697d23cea1b5b86b42e82972be48b4b92ada16e19b081c7e2e41
7
- data.tar.gz: 4467d04227d805798d58f7806ae6f0f8a59cd7b81070126ecb9462104798474d0f508fd705dead75fa86c87607aa2a7c784224fd4270fb75c27ef3fdb77ffd2d
6
+ metadata.gz: 176d12530d09b496dd051ea70b8694ceda11307b301265114fb64aa46c76564b7a82304489508e37ea0adfedc95656badf0ba0d24aa74236fb06dee5a221835d
7
+ data.tar.gz: 4ba9d2490ce1564cf202803346fa8661b83e960743161113a9d3248c89e3d618792d57558c3397d2f224470b17ff5a39805344b80eb40ea306825f75a963ea98
data/Gemfile CHANGED
@@ -1,3 +1,2 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
-
data/README.md CHANGED
@@ -24,7 +24,7 @@ output {
24
24
 
25
25
  ```
26
26
 
27
- More configuration details please refer to [code part](lib/logstash/outputs/qingstor.rb).
27
+ More configuration details please refer to [common options](/docs/index.asciidoc).
28
28
 
29
29
  ## 2. Running your unpublished Plugin in Logstash
30
30
 
@@ -1,12 +1,14 @@
1
1
  # encoding: utf-8
2
- require "java"
3
- require "concurrent"
4
- require "concurrent/timer_task"
5
- require "logstash/util"
2
+
3
+ require 'logstash/util'
4
+ require 'logstash/outputs/qingstor'
5
+ require 'java'
6
+ require 'concurrent'
7
+ require 'concurrent/timer_task'
6
8
 
7
9
  ConcurrentHashMap = java.util.concurrent.ConcurrentHashMap
8
10
 
9
- module LogStash
11
+ module LogStash
10
12
  module Outputs
11
13
  class Qingstor
12
14
  class FileRepository
@@ -20,22 +22,25 @@ module LogStash
20
22
  end
21
23
 
22
24
  def with_lock
23
- @lock.synchronize {
25
+ @lock.synchronize do
24
26
  yield @file_factory
25
- }
26
- end
27
+ end
28
+ end
27
29
 
28
30
  def stale?
29
- with_lock { |factory| factory.current.size == 0 && (Time.now - factory.current.ctime > @stale_time) }
30
- end
31
+ with_lock do |factory|
32
+ factory.current.empty? &&
33
+ (Time.now - factory.current.ctime > @stale_time)
34
+ end
35
+ end
31
36
 
32
- def apply(prefix)
33
- return self
34
- end
37
+ def apply(_prefix)
38
+ self
39
+ end
35
40
 
36
- def delete!
41
+ def delete!
37
42
  with_lock { |factory| factory.current.delete! }
38
- end
43
+ end
39
44
  end
40
45
 
41
46
  class FactoryInitializer
@@ -44,69 +49,79 @@ module LogStash
44
49
  @encoding = encoding
45
50
  @temporary_directory = temporary_directory
46
51
  @stale_time = stale_time
47
- end
52
+ end
48
53
 
49
54
  def apply(prefix_key)
50
- PrefixedValue.new(TemporaryFileFactory.new(prefix_key, @tags, @encoding, @temporary_directory), @stale_time)
51
- end
52
- end
55
+ PrefixedValue.new(
56
+ TemporaryFileFactory.new(prefix_key, @tags, @encoding,
57
+ @temporary_directory),
58
+ @stale_time
59
+ )
60
+ end
61
+ end
53
62
 
54
63
  def initialize(tags, encoding, temporary_directory,
55
64
  stale_time = DEFAULT_STATE_TIME_SECS,
56
65
  sweeper_interval = DEFAULT_STATE_SWEEPER_INTERVAL_SECS)
57
- @prefixed_factories = ConcurrentHashMap.new
66
+ @prefixed_factories = ConcurrentHashMap.new
58
67
  @sweeper_interval = sweeper_interval
59
- @factoryinitializer = FactoryInitializer.new(tags, encoding, temporary_directory, stale_time)
68
+ @factoryinitializer = FactoryInitializer.new(tags,
69
+ encoding,
70
+ temporary_directory,
71
+ stale_time)
60
72
 
61
73
  start_stale_sweeper
62
74
  end
63
75
 
64
76
  def keys
65
77
  @prefixed_factories.keySet
66
- end
78
+ end
67
79
 
68
- def each_files
80
+ def each_files
69
81
  @prefixed_factories.elements.each do |prefixed_file|
70
82
  prefixed_file.with_lock { |factory| yield factory.current }
71
- end
72
- end
83
+ end
84
+ end
73
85
 
74
86
  def get_factory(prefix_key)
75
- @prefixed_factories.computeIfAbsent(prefix_key, @factoryinitializer).with_lock { |factory| yield factory }
76
- end
87
+ @prefixed_factories.computeIfAbsent(prefix_key, @factoryinitializer)
88
+ .with_lock { |factory| yield factory }
89
+ end
77
90
 
78
91
  def get_file(prefix_key)
79
92
  get_factory(prefix_key) { |factory| yield factory.current }
80
- end
93
+ end
81
94
 
82
- def shutdown
83
- stop_stale_sweeper
84
- end
95
+ def shutdown
96
+ stop_stale_sweeper
97
+ end
98
+
99
+ def size
100
+ @prefixed_factories.size
101
+ end
85
102
 
86
- def size
87
- @prefixed_factories.size
88
- end
89
-
90
103
  def remove_stale(k, v)
91
- if v.stale?
104
+ if v.stale?
92
105
  @prefixed_factories.remove(k, v)
93
106
  v.delete!
94
- end
95
- end
107
+ end
108
+ end
96
109
 
97
- def start_stale_sweeper
98
- @stale_sweeper = Concurrent::TimerTask.new(:execution_interval => @sweeper_interval) do
99
- LogStash::Util.set_thread_name("Qingstor, stale factory sweeper")
110
+ def start_stale_sweeper
111
+ @stale_sweeper = Concurrent::TimerTask.new(
112
+ :execution_interval => @sweeper_interval
113
+ ) do
114
+ LogStash::Util.set_thread_name('Qingstor, stale factory sweeper')
100
115
  @prefixed_factories.forEach { |k, v| remove_stale(k, v) }
101
- end
116
+ end
102
117
 
103
118
  @stale_sweeper.execute
104
- end
119
+ end
105
120
 
106
- def stop_stale_sweeper
121
+ def stop_stale_sweeper
107
122
  @stale_sweeper.shutdown
108
- end
109
- end
110
- end
111
- end
112
- end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -1,30 +1,31 @@
1
1
  # encoding: utf-8
2
- require "qingstor/sdk"
3
- require "fileutils"
2
+
3
+ require 'logstash/outputs/qingstor'
4
+ require 'qingstor/sdk'
4
5
 
5
6
  module LogStash
6
7
  module Outputs
7
8
  class Qingstor
8
- class QingstorValidator
9
-
9
+ module QingstorValidator
10
10
  def self.bucket_valid?(bucket)
11
11
  res = bucket.head
12
- case res[:status_code]
12
+ case res[:status_code]
13
13
  when 401
14
- raise LogStash::ConfigurationError, "Incorrect key id or access key."
14
+ raise LogStash::ConfigurationError, 'Incorrect key id/access key.'
15
15
  when 404
16
- raise LogStash::ConfigurationError, "Incorrect bucket/region name."
17
- end
18
- true
19
- end
16
+ raise LogStash::ConfigurationError, 'Incorrect bucket/region name.'
17
+ end
18
+ true
19
+ end
20
20
 
21
21
  def self.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
22
+ if prefix.start_with?('/') || prefix.length >= 1024
23
+ raise LogStash::ConfigurationError, 'Prefix must not start with'\
24
+ + " '/' and with length less than 1024 "
25
+ end
25
26
  true
26
- end
27
- end
28
- end
29
- end
30
- end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,71 +1,78 @@
1
1
  # encoding: utf-8
2
- module LogStash
3
- module Outputs
2
+
3
+ require 'logstash/outputs/qingstor'
4
+
5
+ module LogStash
6
+ module Outputs
4
7
  class Qingstor
5
8
  class RotationPolicy
6
-
7
9
  def initialize(policy, file_size, file_time)
8
10
  @policy = policy
9
11
  case policy
10
- when "time"
12
+ when 'time'
11
13
  init_time(file_time)
12
- when "size"
14
+ when 'size'
13
15
  init_size(file_size)
14
- when "size_and_time"
16
+ when 'size_and_time'
15
17
  init_size(file_size)
16
- init_time(file_time)
17
- end
18
- end
18
+ init_time(file_time)
19
+ end
20
+ end
19
21
 
20
22
  def init_size(file_size)
21
23
  if file_size <= 0
22
- raise LogStash::ConfigurationError, "'file_size' need to be greater than 0"
24
+ raise LogStash::ConfigurationError, "'file_size' need to "\
25
+ + 'be greater than 0'
23
26
  end
24
27
  @file_size = file_size
25
- end
28
+ end
26
29
 
27
30
  def init_time(file_time)
28
31
  if file_time <= 0
29
- raise LogStash::ConfigurationError, "'file_time' need to be greater than 0"
30
- end
32
+ raise LogStash::ConfigurationError, "'file_time' need to "\
33
+ + 'be greater than 0'
34
+ end
31
35
  @file_time = file_time
32
- end
36
+ end
33
37
 
34
38
  def rotate?(file)
35
39
  case @policy
36
- when "time"
40
+ when 'time'
37
41
  time_rotate?(file)
38
- when "size"
42
+ when 'size'
39
43
  size_rotate?(file)
40
- when "size_and_time"
44
+ when 'size_and_time'
41
45
  size_and_time_rotate?(file)
42
46
  end
43
- end
47
+ end
44
48
 
45
49
  def size_and_time_rotate?(file)
46
50
  size_rotate?(file) || time_rotate?(file)
47
- end
51
+ end
48
52
 
49
53
  def size_rotate?(file)
50
54
  file.size >= @file_size
51
- end
55
+ end
52
56
 
53
57
  def time_rotate?(file)
54
- file.size > 0 && (Time.now - file.ctime) >= @file_time
55
- end
58
+ !file.empty? && (Time.now - file.ctime) >= @file_time
59
+ end
56
60
 
57
61
  def needs_periodic?
58
62
  case @policy
59
- when "time" then
63
+ when 'time' then
60
64
  true
61
- when "size_and_time" then
65
+ when 'size_and_time' then
62
66
  true
63
67
  else
64
68
  false
65
69
  end
66
70
  end
67
71
 
68
- end
69
- end
70
- end
71
- end
72
+ def to_s
73
+ "#{@policy} #{@file_time} #{@file_size}"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,8 +1,10 @@
1
1
  # encoding: utf-8
2
- require "thread"
3
- require "forwardable"
4
- require "fileutils"
5
- require "pathname"
2
+
3
+ require 'logstash/outputs/qingstor'
4
+ require 'thread'
5
+ require 'forwardable'
6
+ require 'fileutils'
7
+ require 'pathname'
6
8
 
7
9
  module LogStash
8
10
  module Outputs
@@ -15,49 +17,49 @@ module LogStash
15
17
  attr_reader :fd
16
18
 
17
19
  def initialize(key, fd, tmp_path)
18
- @key = key
20
+ @key = key
19
21
  @fd = fd
20
22
  @tmp_path = tmp_path
21
23
  @created_at = Time.now
22
- end
24
+ end
23
25
 
24
- def ctime
25
- @created_at
26
- end
27
-
28
- def tmp_path
29
- @tmp_path
30
- end
26
+ def ctime
27
+ @created_at
28
+ end
31
29
 
32
- def size
33
- begin
34
- @fd.size
35
- rescue IOError
36
- ::File.size(path)
37
- end
38
- end
30
+ attr_reader :tmp_path
39
31
 
40
- def key
41
- @key.gsub(/^\//, "")
42
- end
32
+ def size
33
+ @fd.size
34
+ rescue IOError
35
+ ::File.size(path)
36
+ end
37
+
38
+ def key
39
+ @key.gsub(/^\//, '')
40
+ end
43
41
 
44
42
  def delete!
45
- @fd.close rescue IOError
43
+ begin
44
+ @fd.close
45
+ rescue
46
+ IOError
47
+ end
46
48
  FileUtils.rm_r(@tmp_path, :secure => true)
47
- end
49
+ end
48
50
 
49
51
  def empty?
50
- size == 0
51
- end
52
+ size.zero?
53
+ end
52
54
 
53
55
  def self.create_from_existing_file(file_path, tmp_folder)
54
- key_parts = Pathname.new(file_path).relative_path_from(tmp_folder).to_s.split(::File::SEPARATOR)
55
- TemporaryFile.new(key_parts.slice(1, key_parts.size).join("/"),
56
- ::File.open(file_path, "r"),
56
+ key_parts = Pathname.new(file_path).relative_path_from(tmp_folder)
57
+ .to_s.split(::File::SEPARATOR)
58
+ TemporaryFile.new(key_parts.slice(1, key_parts.size).join('/'),
59
+ ::File.open(file_path, 'r'),
57
60
  ::File.join(tmp_folder, key_parts.slice(0, 1)))
58
-
59
- end
60
- end
61
- end
62
- end
63
- end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,19 +1,21 @@
1
1
  # encoding: utf-8
2
- require "socket"
3
- require "securerandom"
4
- require "fileutils"
5
- require "zlib"
6
- require "forwardable"
2
+
3
+ require 'logstash/outputs/qingstor'
4
+ require 'socket'
5
+ require 'securerandom'
6
+ require 'fileutils'
7
+ require 'zlib'
8
+ require 'forwardable'
7
9
 
8
10
  module LogStash
9
11
  module Outputs
10
12
  class Qingstor
11
13
  class TemporaryFileFactory
12
- FILE_MODE = "a"
13
- GZIP_ENCODING = "gzip"
14
- GZIP_EXTENSION = "log.gz"
15
- TXT_EXTENSION = "log"
16
- STRFTIME = "%Y-%m-%dT%H.%M"
14
+ FILE_MODE = 'a'.freeze
15
+ GZIP_ENCODING = 'gzip'.freeze
16
+ GZIP_EXTENSION = 'log.gz'.freeze
17
+ TXT_EXTENSION = 'log'.freeze
18
+ STRFTIME = '%Y-%m-%dT%H.%M'.freeze
17
19
 
18
20
  attr_accessor :counter, :tags, :prefix, :encoding, :tmpdir, :current
19
21
 
@@ -23,88 +25,90 @@ module LogStash
23
25
  @tags = tags
24
26
  @encoding = encoding
25
27
  @tmpdir = tmpdir
26
- @lock = Mutex.new
28
+ @lock = Mutex.new
27
29
 
28
30
  rotate!
29
- end
31
+ end
30
32
 
31
33
  def rotate!
32
- @lock.synchronize {
34
+ @lock.synchronize do
33
35
  @current = new_file
34
36
  increment_counter
35
- @current
36
- }
37
- end
37
+ @current
38
+ end
39
+ end
40
+
41
+ private
38
42
 
39
- private
40
43
  def extension
41
44
  gzip? ? GZIP_EXTENSION : TXT_EXTENSION
42
- end
43
-
45
+ end
46
+
44
47
  def gzip?
45
48
  encoding == GZIP_ENCODING
46
- end
49
+ end
47
50
 
48
51
  def increment_counter
49
52
  @counter += 1
50
- end
53
+ end
51
54
 
52
- def current_time
55
+ def current_time
53
56
  Time.new.strftime(STRFTIME)
54
- end
57
+ end
55
58
 
56
- def generate_name
59
+ def generate_name
57
60
  filename = "ls.qingstor.#{SecureRandom.uuid}.#{current_time}"
58
61
 
59
- if tags.size > 0
62
+ if !tags.empty?
60
63
  "#{filename}.tag_#{tags.join('.')}.part#{counter}.#{extension}"
61
- else
64
+ else
62
65
  "#{filename}.part#{counter}.#{extension}"
63
- end
64
- end
66
+ end
67
+ end
65
68
 
66
- def new_file
67
- uuid = SecureRandom.uuid
68
- name = generate_name
69
+ def new_file
70
+ uuid = SecureRandom.uuid
71
+ name = generate_name
69
72
  path = ::File.join(@tmpdir, uuid)
70
73
  key = ::File.join(@prefix, name)
71
74
 
72
75
  FileUtils.mkdir_p(::File.join(path, @prefix))
73
76
 
74
- io = if gzip?
75
- IOWrappedGzip.new(::File.open(::File.join(path, key), FILE_MODE))
76
- else
77
+ io = if gzip?
78
+ IOWrappedGzip.new(::File.open(::File.join(path, key),
79
+ FILE_MODE))
80
+ else
77
81
  ::File.open(::File.join(path, key), FILE_MODE)
78
- end
82
+ end
79
83
 
80
84
  TemporaryFile.new(key, io, path)
81
85
  end
82
86
 
83
- class IOWrappedGzip
84
- extend Forwardable
87
+ class IOWrappedGzip
88
+ extend Forwardable
85
89
 
86
90
  def_delegators :@gzip_writer, :write, :close
87
91
  attr_accessor :file_io, :gzip_writer
88
-
92
+
89
93
  def initialize(file_io)
90
94
  @file_io = file_io
91
95
  @gzip_writer = Zlib::GzipWriter.open(file_io)
92
- end
93
-
94
- def path
95
- @gzip_writer.to_io.path
96
- end
97
-
98
- def size
99
- @gzip_writer.flush
100
- @gzip_writer.to_io.size
101
- end
102
-
103
- def fsync
104
- @gzip_writer.to_io.fsync
105
- end
106
- end
107
- end
108
- end
109
- end
110
- end
96
+ end
97
+
98
+ def path
99
+ @gzip_writer.to_io.path
100
+ end
101
+
102
+ def size
103
+ @gzip_writer.flush
104
+ @gzip_writer.to_io.size
105
+ end
106
+
107
+ def fsync
108
+ @gzip_writer.to_io.fsync
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end