microsoft-sentinel-log-analytics-logstash-output-plugin 1.1.4 → 2.2.1-java

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.
@@ -1,47 +0,0 @@
1
- # encoding: utf-8
2
- require "logstash/sentinel_la/logstashLoganalyticsConfiguration"
3
- require "logstash/sentinel_la/eventsHandler"
4
- require "logstash/sentinel_la/logStashAutoResizeBuffer"
5
- require "logstash/sentinel_la/logStashCompressedStream"
6
-
7
- module LogStash; module Outputs; class MicrosoftSentinelOutputInternal
8
- class LogsSender < EventsHandler
9
-
10
- @thread_batch_map
11
-
12
- def initialize(logstashLogAnalyticsConfiguration)
13
- @thread_batch_map = Concurrent::Hash.new
14
- @logstashLogAnalyticsConfiguration = logstashLogAnalyticsConfiguration
15
- @logger = logstashLogAnalyticsConfiguration.logger
16
- super
17
- end
18
-
19
- def handle_events(events)
20
- t = Thread.current
21
-
22
- unless @thread_batch_map.include?(t)
23
- @thread_batch_map[t] = @logstashLogAnalyticsConfiguration.compress_data ?
24
- LogStashCompressedStream::new(@logstashLogAnalyticsConfiguration) :
25
- LogStashAutoResizeBuffer::new(@logstashLogAnalyticsConfiguration)
26
- end
27
-
28
- events.each do |event|
29
- # creating document from event
30
- document = create_event_document(event)
31
-
32
- # Skip if document doesn't contain any items
33
- next if (document.keys).length < 1
34
-
35
- @logger.trace("Adding event document - " + event.to_s)
36
- @thread_batch_map[t].batch_event_document(document)
37
- end
38
- end
39
-
40
- def close
41
- @thread_batch_map.each { |thread_id, batcher|
42
- batcher.close
43
- }
44
- end
45
-
46
- end
47
- end; end; end;
@@ -1,243 +0,0 @@
1
- # encoding: utf-8
2
- module LogStash; module Outputs; class MicrosoftSentinelOutputInternal
3
- class LogstashLoganalyticsOutputConfiguration
4
- def initialize(client_app_Id, client_app_secret, tenant_id, data_collection_endpoint, dcr_immutable_id, dcr_stream_name, compress_data, create_sample_file, sample_file_path, logger)
5
- @client_app_Id = client_app_Id
6
- @client_app_secret = client_app_secret
7
- @tenant_id = tenant_id
8
- @data_collection_endpoint = data_collection_endpoint
9
- @dcr_immutable_id = dcr_immutable_id
10
- @dcr_stream_name = dcr_stream_name
11
- @logger = logger
12
- @compress_data = compress_data
13
- @create_sample_file = create_sample_file
14
- @sample_file_path = sample_file_path
15
-
16
- # Delay between each resending of a message
17
- @RETRANSMISSION_DELAY = 2
18
- @MIN_MESSAGE_AMOUNT = 100
19
- # Maximum of 1 MB per post to Log Analytics Data Collector API V2.
20
- # This is a size limit for a single post.
21
- # If the data from a single post that exceeds 1 MB, you should split it.
22
- @loganalytics_api_data_limit = 1 * 1024 * 1024
23
-
24
- # Taking 4K safety buffer
25
- @MAX_SIZE_BYTES = @loganalytics_api_data_limit - 10000
26
-
27
- @azure_clouds = {
28
- "AzureCloud" => {"aad" => "https://login.microsoftonline.com", "monitor" => "https://monitor.azure.com"},
29
- "AzureChinaCloud" => {"aad" => "https://login.chinacloudapi.cn", "monitor" => "https://monitor.azure.cn"},
30
- "AzureUSGovernment" => {"aad" => "https://login.microsoftonline.us", "monitor" => "https://monitor.azure.us"}
31
- }.freeze
32
- end
33
-
34
- def validate_configuration()
35
- if @create_sample_file
36
- begin
37
- if @sample_file_path.nil?
38
- print_missing_parameter_message_and_raise("sample_file_path")
39
- end
40
- if @sample_file_path.strip == ""
41
- raise ArgumentError, "The setting sample_file_path cannot be empty"
42
- end
43
- begin
44
- file = java.io.File.new(@sample_file_path)
45
- if !file.exists
46
- raise "Path not exists"
47
- end
48
- rescue Exception
49
- raise ArgumentError, "The path #{@sample_file_path} does not exist."
50
- end
51
- end
52
- else
53
- required_configs = { "client_app_Id" => @client_app_Id,
54
- "client_app_secret" => @client_app_secret,
55
- "tenant_id" => @tenant_id,
56
- "data_collection_endpoint" => @data_collection_endpoint,
57
- "dcr_immutable_id" => @dcr_immutable_id,
58
- "dcr_stream_name" => @dcr_stream_name }
59
- required_configs.each { |name, conf|
60
- if conf.nil?
61
- print_missing_parameter_message_and_raise(name)
62
- end
63
- if conf.empty?
64
- raise ArgumentError, "Malformed configuration , the following arguments can not be null or empty.[client_app_Id, client_app_secret, tenant_id, data_collection_endpoint, dcr_immutable_id, dcr_stream_name]"
65
- end
66
- }
67
-
68
- if @retransmission_time < 0
69
- raise ArgumentError, "retransmission_time must be a positive integer."
70
- end
71
- if @max_items < @MIN_MESSAGE_AMOUNT
72
- raise ArgumentError, "Setting max_items to value must be greater then #{@MIN_MESSAGE_AMOUNT}."
73
- end
74
- if @key_names.length > 500
75
- raise ArgumentError, 'There are over 500 key names listed to be included in the events sent to Azure Loganalytics, which exceeds the limit of columns that can be define in each table in log analytics.'
76
- end
77
- if !@azure_clouds.key?(@azure_cloud)
78
- raise ArgumentError, "The specified Azure cloud #{@azure_cloud} is not supported. Supported clouds are: #{@azure_clouds.keys.join(", ")}."
79
- end
80
- end
81
- @logger.info("Azure Loganalytics configuration was found valid.")
82
- # If all validation pass then configuration is valid
83
- return true
84
- end # def validate_configuration
85
-
86
-
87
- def print_missing_parameter_message_and_raise(param_name)
88
- @logger.error("Missing a required setting for the microsoft-sentinel-log-analytics-logstash-output-plugin output plugin:
89
- output {
90
- microsoft-sentinel-log-analytics-logstash-output-plugin {
91
- #{param_name} => # SETTING MISSING
92
- ...
93
- }
94
- }
95
- ")
96
- raise ArgumentError, "The setting #{param_name} is required."
97
- end
98
-
99
- def RETRANSMISSION_DELAY
100
- @RETRANSMISSION_DELAY
101
- end
102
-
103
- def MAX_SIZE_BYTES
104
- @MAX_SIZE_BYTES
105
- end
106
-
107
- def amount_resizing
108
- @amount_resizing
109
- end
110
-
111
- def retransmission_time
112
- @retransmission_time
113
- end
114
-
115
- def proxy_aad
116
- @proxy_aad
117
- end
118
-
119
- def proxy_endpoint
120
- @proxy_endpoint
121
- end
122
-
123
- def logger
124
- @logger
125
- end
126
-
127
- def decrease_factor
128
- @decrease_factor
129
- end
130
-
131
- def client_app_Id
132
- @client_app_Id
133
- end
134
-
135
- def client_app_secret
136
- @client_app_secret
137
- end
138
-
139
- def tenant_id
140
- @tenant_id
141
- end
142
-
143
- def data_collection_endpoint
144
- @data_collection_endpoint
145
- end
146
-
147
- def dcr_immutable_id
148
- @dcr_immutable_id
149
- end
150
-
151
- def dcr_stream_name
152
- @dcr_stream_name
153
- end
154
-
155
- def key_names
156
- @key_names
157
- end
158
-
159
- def max_items
160
- @max_items
161
- end
162
-
163
- def plugin_flush_interval
164
- @plugin_flush_interval
165
- end
166
-
167
- def MIN_MESSAGE_AMOUNT
168
- @MIN_MESSAGE_AMOUNT
169
- end
170
-
171
- def key_names=(new_key_names)
172
- @key_names = new_key_names
173
- end
174
-
175
- def plugin_flush_interval=(new_plugin_flush_interval)
176
- @plugin_flush_interval = new_plugin_flush_interval
177
- end
178
-
179
- def decrease_factor=(new_decrease_factor)
180
- @decrease_factor = new_decrease_factor
181
- end
182
-
183
- def amount_resizing=(new_amount_resizing)
184
- @amount_resizing = new_amount_resizing
185
- end
186
-
187
- def max_items=(new_max_items)
188
- @max_items = new_max_items
189
- end
190
-
191
- def proxy_aad=(new_proxy_aad)
192
- @proxy_aad = new_proxy_aad
193
- end
194
-
195
- def proxy_endpoint=(new_proxy_endpoint)
196
- @proxy_endpoint = new_proxy_endpoint
197
- end
198
-
199
- def retransmission_time=(new_retransmission_time)
200
- @retransmission_time = new_retransmission_time
201
- end
202
-
203
- def compress_data
204
- @compress_data
205
- end
206
-
207
- def compress_data=(new_compress_data)
208
- @compress_data = new_compress_data
209
- end
210
-
211
- def create_sample_file
212
- @create_sample_file
213
- end
214
-
215
- def create_sample_file=(new_create_sample_file)
216
- @create_sample_file = new_create_sample_file
217
- end
218
-
219
- def sample_file_path
220
- @sample_file_path
221
- end
222
-
223
- def sample_file_path=(new_sample_file_path)
224
- @sample_file_path = new_sample_file_path
225
- end
226
-
227
- def azure_cloud
228
- @azure_cloud
229
- end
230
-
231
- def azure_cloud=(new_azure_cloud)
232
- @azure_cloud = new_azure_cloud
233
- end
234
-
235
- def get_aad_endpoint
236
- @azure_clouds[@azure_cloud]["aad"]
237
- end
238
-
239
- def get_monitor_endpoint
240
- @azure_clouds[@azure_cloud]["monitor"]
241
- end
242
- end
243
- end ;end ;end
@@ -1,61 +0,0 @@
1
- # encoding: utf-8
2
- require "logstash/sentinel_la/logstashLoganalyticsConfiguration"
3
- require "logstash/sentinel_la/eventsHandler"
4
-
5
- module LogStash
6
- module Outputs
7
- class MicrosoftSentinelOutputInternal
8
- class SampleFileCreator < EventsHandler
9
-
10
- def initialize(logstashLogAnalyticsConfiguration)
11
- @events_buffer = Concurrent::Array.new
12
- @maximum_events_to_sample = 10
13
- @was_file_written = false
14
- @writing_mutex = Mutex.new
15
- super
16
- end
17
-
18
- def handle_events(events)
19
- events.each do |event|
20
- if !@was_file_written
21
- filtered_event = create_event_document(event)
22
- @events_buffer.push(filtered_event)
23
- end
24
- end
25
- try_writing_events_to_file
26
- end
27
-
28
- def close
29
- try_writing_events_to_file(true)
30
- end
31
-
32
- def try_writing_events_to_file(force = false)
33
- if @was_file_written
34
- return
35
- end
36
-
37
- @writing_mutex.synchronize do
38
- #check if file was written during the wait
39
- if @was_file_written ||
40
- @events_buffer.length == 0 ||
41
- (@events_buffer.length <= @maximum_events_to_sample && !force)
42
- return
43
- end
44
-
45
- output_path = @logstashLogAnalyticsConfiguration.sample_file_path
46
- output_file_name = "sampleFile#{Time.now.to_i}.json"
47
- file = java.io.File.new(output_path,output_file_name)
48
- fw = java.io.FileWriter.new(file)
49
- fw.write(@events_buffer.take(@maximum_events_to_sample).to_json)
50
- fw.flush
51
- fw.close
52
-
53
- @was_file_written = true
54
- @logger.info("Sample file was written in path: #{file.getAbsolutePath}")
55
- end
56
- end
57
-
58
- end
59
- end
60
- end
61
- end
@@ -1,10 +0,0 @@
1
- module LogStash; module Outputs;
2
- class MicrosoftSentinelOutputInternal
3
- VERSION_INFO = [1, 1, 4].freeze
4
- VERSION = VERSION_INFO.map(&:to_s).join('.').freeze
5
-
6
- def self.version
7
- VERSION
8
- end
9
- end
10
- end;end
@@ -1,27 +0,0 @@
1
- require File.expand_path('../lib/logstash/sentinel_la/version', __FILE__)
2
-
3
- Gem::Specification.new do |s|
4
- s.name = 'microsoft-sentinel-log-analytics-logstash-output-plugin'
5
- s.version = LogStash::Outputs::MicrosoftSentinelOutputInternal::VERSION
6
- s.authors = ["Microsoft Sentinel"]
7
- s.email = 'AzureSentinel@microsoft.com'
8
- s.summary = %q{Microsoft Sentinel provides a new output plugin for Logstash. Use this output plugin to send any log via Logstash to the Microsoft Sentinel/Log Analytics workspace. This is done with the Log Analytics DCR-based API.}
9
- s.description = s.summary
10
- s.homepage = "https://github.com/Azure/Azure-Sentinel"
11
- s.licenses = ["MIT"]
12
- s.require_paths = ["lib"]
13
-
14
- # Files
15
- s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
16
- # Tests
17
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
-
19
- # Special flag to let us know this is actually a logstash plugin
20
- s.metadata = { "logstash_plugin" => "true", "logstash_group" => "output" }
21
-
22
- # Gem dependencies
23
- s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
- s.add_runtime_dependency "logstash-codec-plain"
25
- s.add_runtime_dependency "excon", ">= 0.88.0", "< 1.0.0"
26
- s.add_development_dependency "logstash-devutils"
27
- end