logtastic 0.1.0

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