logstash-output-qingstor 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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