logtastic 0.1.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.
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logtastic/setup"
4
+
5
+ module Logtastic
6
+ class ECS
7
+ def initialize(index: nil, template: nil, ilm: nil, version: "1.5", output: :default)
8
+ @index = index
9
+ @output = output
10
+ @elasticsearch = Logtastic.client(@output)
11
+
12
+ @setup = Logtastic::Setup.new(
13
+ @elasticsearch,
14
+ template: { json: { path: File.new(template_path(version)) } }.merge(template || {}),
15
+ ilm: ilm
16
+ )
17
+ @setup.perform!
18
+ end
19
+
20
+ def write(event)
21
+ Logtastic.write(@output, index: write_index(event), body: event)
22
+ end
23
+
24
+ def write_now(event)
25
+ @elasticsearch.index(index: write_index(event), body: event)
26
+ end
27
+
28
+ def search(**args)
29
+ @elasticsearch.search({ index: query_index }.merge(**args))
30
+ end
31
+
32
+ def count(**args)
33
+ @elasticsearch.count({ index: query_index }.merge(**args))
34
+ end
35
+
36
+ def query_index
37
+ if @setup.ilm_enabled?
38
+ "#{@setup.rollover_alias}-*"
39
+ else
40
+ @setup.template_pattern
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def write_index(_event)
47
+ if @index.nil?
48
+ @setup.rollover_alias
49
+ else
50
+ @index
51
+ end
52
+ end
53
+
54
+ def template_path(version)
55
+ File.join(__dir__, "ecs-template-#{version}.json")
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Logtastic
6
+ class Setup
7
+ class Error < StandardError; end
8
+ class AliasAlreadyExists < Error; end
9
+
10
+ DEFAULT_ILM_POLICY = {
11
+ "policy" => {
12
+ "phases" => {
13
+ "hot" => {
14
+ "actions" => {
15
+ "rollover" => {
16
+ "max_size" => "50gb",
17
+ "max_age" => "30d"
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
23
+ }.freeze
24
+
25
+ def initialize(elasticsearch, template: nil, ilm: nil)
26
+ @elasticsearch = elasticsearch
27
+ @template = template || {}
28
+ @ilm = ilm || {}
29
+ end
30
+
31
+ def perform!
32
+ @elasticsearch.xpack.ilm.put_policy(put_ilm_policy_args) if put_ilm_policy?
33
+ @elasticsearch.indices.put_template(put_template_args) if put_template?
34
+
35
+ begin
36
+ @elasticsearch.indices.create(create_rollover_alias_args) if create_rollover_alias?
37
+ rescue Elasticsearch::Transport::Transport::Errors::BadRequest
38
+ raise AliasAlreadyExists, "An index exists with the same name as the alias [#{rollover_alias}]"
39
+ end
40
+
41
+ true
42
+ end
43
+
44
+ def ilm_enabled?
45
+ @ilm.fetch(:enabled, true)
46
+ end
47
+
48
+ def ilm_overwrite?
49
+ @ilm.fetch(:overwrite, false)
50
+ end
51
+
52
+ def ilm_policy_id
53
+ @ilm.fetch(:policy_name, "logtastic")
54
+ end
55
+
56
+ def rollover_alias
57
+ @ilm.fetch(:rollover_alias, "logtastic")
58
+ end
59
+
60
+ def ilm_pattern
61
+ @ilm.fetch(:pattern, "{now/d}-000001")
62
+ end
63
+
64
+ def ilm_policy_body
65
+ policy_file = @ilm.fetch(:policy_file, DEFAULT_ILM_POLICY)
66
+
67
+ if policy_file.is_a?(Hash)
68
+ policy_file
69
+ else
70
+ JSON.load(policy_file)
71
+ end
72
+ end
73
+
74
+ def put_ilm_policy?
75
+ return false unless ilm_enabled?
76
+ return true if ilm_overwrite?
77
+
78
+ begin
79
+ @elasticsearch.xpack.ilm.get_policy(policy_id: ilm_policy_id)
80
+ false
81
+ rescue Elasticsearch::Transport::Transport::Errors::NotFound
82
+ true
83
+ end
84
+ end
85
+
86
+ def put_ilm_policy_args
87
+ {
88
+ policy_id: ilm_policy_id,
89
+ body: ilm_policy_body
90
+ }
91
+ end
92
+
93
+ def template_name
94
+ @template.fetch(:name, "logtastic")
95
+ end
96
+
97
+ def template_pattern
98
+ @template.fetch(:pattern, "logtastic-*")
99
+ end
100
+
101
+ def template_body
102
+ JSON.load(@template.dig(:json, :path)).tap do |base_template|
103
+ index_patterns = Array(template_pattern)
104
+ base_template["index_patterns"] = index_patterns unless index_patterns.empty?
105
+ base_template["settings"]["index"].merge!(template_index_settings)
106
+ end
107
+ end
108
+
109
+ def template_index_settings
110
+ {}.tap do |hash|
111
+ if ilm_enabled?
112
+ hash.merge!(
113
+ "lifecycle.name" => ilm_policy_id,
114
+ "lifecycle.rollover_alias" => rollover_alias
115
+ )
116
+ end
117
+
118
+ hash.merge!(@template.dig(:settings, :index)) if @template.dig(:settings, :index)
119
+ end
120
+ end
121
+
122
+ def template_overwrite?
123
+ @template.fetch(:overwrite, false)
124
+ end
125
+
126
+ def put_template?
127
+ return true if template_overwrite?
128
+
129
+ !@elasticsearch.indices.exists_template?(name: template_name)
130
+ end
131
+
132
+ def put_template_args
133
+ {
134
+ name: template_name,
135
+ create: !template_overwrite?,
136
+ body: template_body
137
+ }
138
+ end
139
+
140
+ def create_rollover_alias?
141
+ return false unless ilm_enabled?
142
+
143
+ !@elasticsearch.indices.exists_alias?(name: rollover_alias)
144
+ end
145
+
146
+ def create_rollover_alias_args
147
+ {
148
+ index: "<#{rollover_alias}-#{ilm_pattern}>",
149
+ body: {
150
+ "aliases" => {
151
+ rollover_alias => {
152
+ "is_write_index" => true
153
+ }
154
+ }
155
+ }
156
+ }
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logtastic
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/logtastic/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "logtastic"
5
+ spec.version = Logtastic::VERSION
6
+ spec.authors = ["Orhan Toy"]
7
+ spec.email = ["toyorhan@gmail.com"]
8
+
9
+ spec.summary = "Logtastic"
10
+ spec.description = "Logtastic"
11
+ spec.homepage = "https://github.com/orhantoy/logtastic"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+
14
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/orhantoy/logtastic"
18
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency "elasticsearch"
30
+ spec.add_dependency "elasticsearch-xpack"
31
+ spec.add_dependency "concurrent-ruby"
32
+
33
+ spec.add_development_dependency "byebug"
34
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logtastic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Orhan Toy
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: elasticsearch
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: elasticsearch-xpack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: concurrent-ruby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Logtastic
70
+ email:
71
+ - toyorhan@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - CODE_OF_CONDUCT.md
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - Rakefile
81
+ - bin/console
82
+ - bin/setup
83
+ - lib/logtastic.rb
84
+ - lib/logtastic/ecs-template-1.5.json
85
+ - lib/logtastic/ecs.rb
86
+ - lib/logtastic/setup.rb
87
+ - lib/logtastic/version.rb
88
+ - logtastic.gemspec
89
+ homepage: https://github.com/orhantoy/logtastic
90
+ licenses: []
91
+ metadata:
92
+ homepage_uri: https://github.com/orhantoy/logtastic
93
+ source_code_uri: https://github.com/orhantoy/logtastic
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 2.3.0
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.0.3
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Logtastic
113
+ test_files: []