sumologic-query 1.1.2 → 1.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 +4 -4
- data/lib/sumologic/metadata/parallel_fetcher.rb +63 -0
- data/lib/sumologic/metadata/source.rb +29 -20
- data/lib/sumologic/search/poller.rb +2 -0
- data/lib/sumologic/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7b7bbf8f091fa6d3c6e213a34c1ba72952c43aa995814834379c30a051d3f4f5
|
|
4
|
+
data.tar.gz: 4e7bc3f985d01543a5af7ce89d7746944107d4fd99ecf4367c276a5e550dbdca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f34b22f610d453649fff4926c7dfdff0fd2d5ff18a2e5fa6994cf1f41635990c28ace805fb2508520a1f016899c99f71ba31be2d5b0771a8b30d9e781f310a2
|
|
7
|
+
data.tar.gz: 0a12a47f8ddfeda0bab912f2011a033b121e01f3c63b19d9fa80e7cfa0a7df32a7277784a92a88ca988819a1f42c717c61dbbae79d5bab154161d9cff5f571a8
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sumologic
|
|
4
|
+
module Metadata
|
|
5
|
+
# Handles parallel fetching of sources from multiple collectors
|
|
6
|
+
class ParallelFetcher
|
|
7
|
+
def initialize(max_threads: 10)
|
|
8
|
+
@max_threads = max_threads
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Fetch sources for collectors in parallel
|
|
12
|
+
# Returns array of results with collector info and sources
|
|
13
|
+
def fetch_all(collectors, &block)
|
|
14
|
+
result = []
|
|
15
|
+
mutex = Mutex.new
|
|
16
|
+
queue = create_work_queue(collectors)
|
|
17
|
+
threads = create_workers(queue, result, mutex, &block)
|
|
18
|
+
|
|
19
|
+
threads.each(&:join)
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def create_work_queue(collectors)
|
|
26
|
+
queue = Queue.new
|
|
27
|
+
collectors.each { |collector| queue << collector }
|
|
28
|
+
queue
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create_workers(queue, result, mutex, &block)
|
|
32
|
+
worker_count = [@max_threads, queue.size].min
|
|
33
|
+
|
|
34
|
+
Array.new(worker_count) do
|
|
35
|
+
Thread.new { process_queue(queue, result, mutex, &block) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def process_queue(queue, result, mutex, &block)
|
|
40
|
+
until queue.empty?
|
|
41
|
+
collector = pop_safely(queue)
|
|
42
|
+
break unless collector
|
|
43
|
+
|
|
44
|
+
process_collector(collector, result, mutex, &block)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def pop_safely(queue)
|
|
49
|
+
queue.pop(true)
|
|
50
|
+
rescue ThreadError
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def process_collector(collector, result, mutex, &block)
|
|
55
|
+
collector_result = block.call(collector)
|
|
56
|
+
|
|
57
|
+
mutex.synchronize do
|
|
58
|
+
result << collector_result if collector_result
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'parallel_fetcher'
|
|
4
|
+
|
|
3
5
|
module Sumologic
|
|
4
6
|
module Metadata
|
|
5
7
|
# Handles source metadata operations
|
|
@@ -7,6 +9,7 @@ module Sumologic
|
|
|
7
9
|
def initialize(http_client:, collector_client:)
|
|
8
10
|
@http = http_client
|
|
9
11
|
@collector_client = collector_client
|
|
12
|
+
@parallel_fetcher = ParallelFetcher.new(max_threads: 10)
|
|
10
13
|
end
|
|
11
14
|
|
|
12
15
|
# List sources for a specific collector
|
|
@@ -26,30 +29,15 @@ module Sumologic
|
|
|
26
29
|
|
|
27
30
|
# List all sources from all collectors
|
|
28
31
|
# Returns array of hashes with collector info and their sources
|
|
32
|
+
# Uses parallel fetching with thread pool for better performance
|
|
29
33
|
def list_all
|
|
30
34
|
collectors = @collector_client.list
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
collectors.each do |collector|
|
|
34
|
-
next unless collector['alive'] # Skip offline collectors
|
|
35
|
-
|
|
36
|
-
collector_id = collector['id']
|
|
37
|
-
collector_name = collector['name']
|
|
35
|
+
active_collectors = collectors.select { |c| c['alive'] }
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
log_info "Fetching sources for #{active_collectors.size} active collectors in parallel..."
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
result << {
|
|
44
|
-
'collector' => {
|
|
45
|
-
'id' => collector_id,
|
|
46
|
-
'name' => collector_name,
|
|
47
|
-
'collectorType' => collector['collectorType']
|
|
48
|
-
},
|
|
49
|
-
'sources' => sources
|
|
50
|
-
}
|
|
51
|
-
rescue StandardError => e
|
|
52
|
-
log_error "Failed to fetch sources for collector #{collector_name}: #{e.message}"
|
|
39
|
+
result = @parallel_fetcher.fetch_all(active_collectors) do |collector|
|
|
40
|
+
fetch_collector_sources(collector)
|
|
53
41
|
end
|
|
54
42
|
|
|
55
43
|
log_info "Total: #{result.size} collectors with sources"
|
|
@@ -60,6 +48,27 @@ module Sumologic
|
|
|
60
48
|
|
|
61
49
|
private
|
|
62
50
|
|
|
51
|
+
# Fetch sources for a single collector
|
|
52
|
+
def fetch_collector_sources(collector)
|
|
53
|
+
collector_id = collector['id']
|
|
54
|
+
collector_name = collector['name']
|
|
55
|
+
|
|
56
|
+
log_info "Fetching sources for collector: #{collector_name} (#{collector_id})"
|
|
57
|
+
sources = list(collector_id: collector_id)
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
'collector' => {
|
|
61
|
+
'id' => collector_id,
|
|
62
|
+
'name' => collector_name,
|
|
63
|
+
'collectorType' => collector['collectorType']
|
|
64
|
+
},
|
|
65
|
+
'sources' => sources
|
|
66
|
+
}
|
|
67
|
+
rescue StandardError => e
|
|
68
|
+
log_error "Failed to fetch sources for collector #{collector_name}: #{e.message}"
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
|
|
63
72
|
def log_info(message)
|
|
64
73
|
warn "[Sumologic::Metadata::Source] #{message}" if ENV['SUMO_DEBUG'] || $DEBUG
|
|
65
74
|
end
|
|
@@ -11,6 +11,7 @@ module Sumologic
|
|
|
11
11
|
|
|
12
12
|
# Poll until job completes or times out
|
|
13
13
|
# Returns final job status data
|
|
14
|
+
# Starts polling immediately, then applies exponential backoff
|
|
14
15
|
def poll(job_id)
|
|
15
16
|
start_time = Time.now
|
|
16
17
|
interval = @config.initial_poll_interval
|
|
@@ -32,6 +33,7 @@ module Sumologic
|
|
|
32
33
|
raise Error, "Search job #{state.downcase}"
|
|
33
34
|
end
|
|
34
35
|
|
|
36
|
+
# Sleep after checking status (not before first check)
|
|
35
37
|
sleep interval
|
|
36
38
|
poll_count += 1
|
|
37
39
|
interval = calculate_next_interval(interval)
|
data/lib/sumologic/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sumologic-query
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- patrick204nqh
|
|
@@ -102,6 +102,7 @@ files:
|
|
|
102
102
|
- lib/sumologic/http/authenticator.rb
|
|
103
103
|
- lib/sumologic/http/client.rb
|
|
104
104
|
- lib/sumologic/metadata/collector.rb
|
|
105
|
+
- lib/sumologic/metadata/parallel_fetcher.rb
|
|
105
106
|
- lib/sumologic/metadata/source.rb
|
|
106
107
|
- lib/sumologic/search/job.rb
|
|
107
108
|
- lib/sumologic/search/paginator.rb
|