sumologic-query 1.3.5 → 1.4.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/CHANGELOG.md +31 -0
- data/README.md +1 -1
- data/lib/sumologic/cli/commands/base_command.rb +0 -20
- data/lib/sumologic/cli/commands/{discover_sources_command.rb → discover_source_metadata_command.rb} +4 -4
- data/lib/sumologic/cli/commands/export_content_command.rb +20 -0
- data/lib/sumologic/cli/commands/get_content_command.rb +20 -0
- data/lib/sumologic/cli/commands/get_dashboard_command.rb +20 -0
- data/lib/sumologic/cli/commands/get_lookup_command.rb +20 -0
- data/lib/sumologic/cli/commands/get_monitor_command.rb +20 -0
- data/lib/sumologic/cli/commands/list_apps_command.rb +22 -0
- data/lib/sumologic/cli/commands/list_collectors_command.rb +1 -1
- data/lib/sumologic/cli/commands/list_dashboards_command.rb +22 -0
- data/lib/sumologic/cli/commands/list_fields_command.rb +27 -0
- data/lib/sumologic/cli/commands/list_folders_command.rb +55 -0
- data/lib/sumologic/cli/commands/list_health_events_command.rb +22 -0
- data/lib/sumologic/cli/commands/list_monitors_command.rb +27 -0
- data/lib/sumologic/cli/commands/list_sources_command.rb +2 -9
- data/lib/sumologic/cli/commands/search_command.rb +56 -18
- data/lib/sumologic/cli.rb +290 -12
- data/lib/sumologic/client.rb +207 -12
- data/lib/sumologic/configuration.rb +23 -9
- data/lib/sumologic/http/client.rb +76 -11
- data/lib/sumologic/http/connection_pool.rb +7 -5
- data/lib/sumologic/http/response_handler.rb +65 -1
- data/lib/sumologic/metadata/app.rb +34 -0
- data/lib/sumologic/metadata/content.rb +95 -0
- data/lib/sumologic/metadata/dashboard.rb +104 -0
- data/lib/sumologic/metadata/field.rb +49 -0
- data/lib/sumologic/metadata/folder.rb +89 -0
- data/lib/sumologic/metadata/health_event.rb +35 -0
- data/lib/sumologic/metadata/lookup_table.rb +34 -0
- data/lib/sumologic/metadata/models.rb +2 -80
- data/lib/sumologic/metadata/monitor.rb +113 -0
- data/lib/sumologic/metadata/source.rb +5 -7
- data/lib/sumologic/metadata/{dynamic_source_discovery.rb → source_metadata_discovery.rb} +7 -7
- data/lib/sumologic/version.rb +1 -1
- data/lib/sumologic.rb +23 -1
- metadata +23 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5822fc268d1979e97d6993b7f233b720049f832c4d5d921a75c32ecccc16ce68
|
|
4
|
+
data.tar.gz: f9e1cde6a138f45d70ec4ed2e06b22f87faf9500a6cb4fb7274fe8df787bcba1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 661862b1dfbc17a5729fbffc54c459e9b2e52a996346b0c028179002c606689096c0a191a26d7bb06d737c197f50324eb86e574289a093c4a392b9248a3e2647
|
|
7
|
+
data.tar.gz: fda3e751c1dc953fa10d878288193ffe060dcd9366e9d18e8cad9d8eeaf8a194e0dcaa1f50ca245fdc5ab20a95c7f1b67809add3dbed2aa28341f68130188ffd
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,37 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
6
6
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
8
8
|
and release notes are automatically generated from commit messages.
|
|
9
|
+
## [1.4.0](https://github.com/patrick204nqh/sumologic-query/compare/v1.3.5...v1.4.0) (2026-02-11)
|
|
10
|
+
|
|
11
|
+
### 🎉 New Features
|
|
12
|
+
|
|
13
|
+
- add comprehensive skills documentation for Sumo Logic CLI commands
|
|
14
|
+
- add export-content command with async job handling
|
|
15
|
+
- add get-content command for path-based content lookup
|
|
16
|
+
- add get-lookup and list-apps commands
|
|
17
|
+
- add list-health-events and list-fields commands
|
|
18
|
+
- migrate monitors to search API with status/query filters
|
|
19
|
+
- add support for retrieving monitors and dashboards in the CLI, refactor monitor collection logic for improved readability
|
|
20
|
+
- Enhance Sumo Logic CLI with monitors, folders, and dashboards commands
|
|
21
|
+
- implement aggregation queries and enhance error handling for rate limits
|
|
22
|
+
|
|
23
|
+
### 🐛 Bug Fixes
|
|
24
|
+
|
|
25
|
+
- migrate dashboards from v1 to v2 API
|
|
26
|
+
|
|
27
|
+
### 🔧 Refactoring
|
|
28
|
+
|
|
29
|
+
- clean design for AI agent readiness (v1.4.0)
|
|
30
|
+
|
|
31
|
+
### 📚 Documentation
|
|
32
|
+
|
|
33
|
+
- update naming conventions to match actual codebase
|
|
34
|
+
- reorganize into SDLC structure
|
|
35
|
+
- clarify discover-sources as search-based technique
|
|
36
|
+
- revise architecture overview with enhanced clarity on design philosophy, component structure, and key features
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
9
40
|
## [1.3.5](https://github.com/patrick204nqh/sumologic-query/compare/v1.3.4...v1.3.5) (2025-11-19)
|
|
10
41
|
|
|
11
42
|
### 🎉 New Features
|
data/README.md
CHANGED
|
@@ -78,7 +78,7 @@ sumo-query search -q "YOUR_QUERY" -f "START" -t "END" [OPTIONS]
|
|
|
78
78
|
sumo-query discover-sources [OPTIONS]
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Discovers source names from log data using search aggregation (`* | count by _sourceName, _sourceCategory`). This is not an official Sumo Logic API — it complements `list-sources` by finding runtime sources (CloudWatch, ECS, Lambda streams) that use dynamic `_sourceName` values.
|
|
82
82
|
|
|
83
83
|
**Options:**
|
|
84
84
|
- `-f, --from` - Start time (default: `-24h`)
|
|
@@ -31,26 +31,6 @@ module Sumologic
|
|
|
31
31
|
puts json_output
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
-
|
|
35
|
-
def format_collector(collector)
|
|
36
|
-
{
|
|
37
|
-
id: collector['id'],
|
|
38
|
-
name: collector['name'],
|
|
39
|
-
collectorType: collector['collectorType'],
|
|
40
|
-
alive: collector['alive'],
|
|
41
|
-
category: collector['category']
|
|
42
|
-
}
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def format_source(source)
|
|
46
|
-
{
|
|
47
|
-
id: source['id'],
|
|
48
|
-
name: source['name'],
|
|
49
|
-
category: source['category'],
|
|
50
|
-
sourceType: source['sourceType'],
|
|
51
|
-
alive: source['alive']
|
|
52
|
-
}
|
|
53
|
-
end
|
|
54
34
|
end
|
|
55
35
|
end
|
|
56
36
|
end
|
data/lib/sumologic/cli/commands/{discover_sources_command.rb → discover_source_metadata_command.rb}
RENAMED
|
@@ -6,8 +6,8 @@ require_relative '../../utils/time_parser'
|
|
|
6
6
|
module Sumologic
|
|
7
7
|
class CLI < Thor
|
|
8
8
|
module Commands
|
|
9
|
-
# Handles the discover-
|
|
10
|
-
class
|
|
9
|
+
# Handles the discover-source-metadata command execution
|
|
10
|
+
class DiscoverSourceMetadataCommand < BaseCommand
|
|
11
11
|
def execute
|
|
12
12
|
parse_time_options
|
|
13
13
|
log_discovery_info
|
|
@@ -32,7 +32,7 @@ module Sumologic
|
|
|
32
32
|
|
|
33
33
|
def log_discovery_info
|
|
34
34
|
warn '=' * 60
|
|
35
|
-
warn 'Discovering
|
|
35
|
+
warn 'Discovering Source Metadata'
|
|
36
36
|
warn '=' * 60
|
|
37
37
|
warn "Time Range: #{@original_from} to #{@original_to}"
|
|
38
38
|
if @original_from != @parsed_from || @original_to != @parsed_to
|
|
@@ -46,7 +46,7 @@ module Sumologic
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def perform_discovery
|
|
49
|
-
client.
|
|
49
|
+
client.discover_source_metadata(
|
|
50
50
|
from_time: @parsed_from,
|
|
51
51
|
to_time: @parsed_to,
|
|
52
52
|
time_zone: @parsed_timezone,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the export-content command execution
|
|
9
|
+
class ExportContentCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
content_id = options[:content_id]
|
|
12
|
+
warn "Exporting content #{content_id}..."
|
|
13
|
+
result = client.export_content(content_id: content_id)
|
|
14
|
+
|
|
15
|
+
output_json(result)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the get-content command execution
|
|
9
|
+
class GetContentCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
path = options[:path]
|
|
12
|
+
warn "Looking up content at path: #{path}..."
|
|
13
|
+
content = client.get_content(path: path)
|
|
14
|
+
|
|
15
|
+
output_json(content)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the get-dashboard command execution
|
|
9
|
+
class GetDashboardCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
dashboard_id = options[:dashboard_id]
|
|
12
|
+
warn "Fetching dashboard #{dashboard_id}..."
|
|
13
|
+
dashboard = client.get_dashboard(dashboard_id: dashboard_id)
|
|
14
|
+
|
|
15
|
+
output_json(dashboard)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the get-lookup command execution
|
|
9
|
+
class GetLookupCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
lookup_id = options[:lookup_id]
|
|
12
|
+
warn "Fetching lookup table #{lookup_id}..."
|
|
13
|
+
lookup = client.get_lookup(lookup_id: lookup_id)
|
|
14
|
+
|
|
15
|
+
output_json(lookup)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the get-monitor command execution
|
|
9
|
+
class GetMonitorCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
monitor_id = options[:monitor_id]
|
|
12
|
+
warn "Fetching monitor #{monitor_id}..."
|
|
13
|
+
monitor = client.get_monitor(monitor_id: monitor_id)
|
|
14
|
+
|
|
15
|
+
output_json(monitor)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the list-apps command execution
|
|
9
|
+
class ListAppsCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
warn 'Fetching app catalog...'
|
|
12
|
+
apps = client.list_apps
|
|
13
|
+
|
|
14
|
+
output_json(
|
|
15
|
+
total: apps.size,
|
|
16
|
+
apps: apps
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the list-dashboards command execution
|
|
9
|
+
class ListDashboardsCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
warn 'Fetching dashboards...'
|
|
12
|
+
dashboards = client.list_dashboards(limit: options[:limit] || 100)
|
|
13
|
+
|
|
14
|
+
output_json(
|
|
15
|
+
total: dashboards.size,
|
|
16
|
+
dashboards: dashboards
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the list-fields command execution
|
|
9
|
+
class ListFieldsCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
if options[:builtin]
|
|
12
|
+
warn 'Fetching built-in fields...'
|
|
13
|
+
fields = client.list_builtin_fields
|
|
14
|
+
else
|
|
15
|
+
warn 'Fetching custom fields...'
|
|
16
|
+
fields = client.list_fields
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
output_json(
|
|
20
|
+
total: fields.size,
|
|
21
|
+
fields: fields
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the list-folders command execution
|
|
9
|
+
class ListFoldersCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
if options[:tree]
|
|
12
|
+
fetch_tree
|
|
13
|
+
elsif options[:folder_id]
|
|
14
|
+
fetch_folder
|
|
15
|
+
else
|
|
16
|
+
fetch_personal
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def fetch_personal
|
|
23
|
+
warn 'Fetching personal folder...'
|
|
24
|
+
folder = client.personal_folder
|
|
25
|
+
output_folder_with_children(folder)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def fetch_folder
|
|
29
|
+
folder_id = options[:folder_id]
|
|
30
|
+
warn "Fetching folder #{folder_id}..."
|
|
31
|
+
folder = client.get_folder(folder_id: folder_id)
|
|
32
|
+
output_folder_with_children(folder)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def fetch_tree
|
|
36
|
+
folder_id = options[:folder_id]
|
|
37
|
+
max_depth = options[:depth] || 3
|
|
38
|
+
|
|
39
|
+
if folder_id
|
|
40
|
+
warn "Fetching folder tree for #{folder_id} (depth: #{max_depth})..."
|
|
41
|
+
else
|
|
42
|
+
warn "Fetching personal folder tree (depth: #{max_depth})..."
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
tree = client.folder_tree(folder_id: folder_id, max_depth: max_depth)
|
|
46
|
+
output_json(tree)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def output_folder_with_children(folder)
|
|
50
|
+
output_json(folder)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the list-health-events command execution
|
|
9
|
+
class ListHealthEventsCommand < BaseCommand
|
|
10
|
+
def execute
|
|
11
|
+
warn 'Fetching health events...'
|
|
12
|
+
events = client.list_health_events(limit: options[:limit] || 100)
|
|
13
|
+
|
|
14
|
+
output_json(
|
|
15
|
+
total: events.size,
|
|
16
|
+
healthEvents: events
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
|
|
5
|
+
module Sumologic
|
|
6
|
+
class CLI < Thor
|
|
7
|
+
module Commands
|
|
8
|
+
# Handles the list-monitors command execution
|
|
9
|
+
# Uses the monitors search API for flat, filterable results
|
|
10
|
+
class ListMonitorsCommand < BaseCommand
|
|
11
|
+
def execute
|
|
12
|
+
warn 'Fetching monitors...'
|
|
13
|
+
monitors = client.list_monitors(
|
|
14
|
+
query: options[:query],
|
|
15
|
+
status: options[:status],
|
|
16
|
+
limit: options[:limit] || 100
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
output_json(
|
|
20
|
+
total: monitors.size,
|
|
21
|
+
monitors: monitors
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -24,7 +24,7 @@ module Sumologic
|
|
|
24
24
|
output_json(
|
|
25
25
|
collector_id: options[:collector_id],
|
|
26
26
|
total: sources.size,
|
|
27
|
-
sources: sources
|
|
27
|
+
sources: sources
|
|
28
28
|
)
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -37,16 +37,9 @@ module Sumologic
|
|
|
37
37
|
output_json(
|
|
38
38
|
total_collectors: all_sources.size,
|
|
39
39
|
total_sources: all_sources.sum { |c| c['sources'].size },
|
|
40
|
-
data: all_sources
|
|
40
|
+
data: all_sources
|
|
41
41
|
)
|
|
42
42
|
end
|
|
43
|
-
|
|
44
|
-
def format_collector_with_sources(item)
|
|
45
|
-
{
|
|
46
|
-
collector: item['collector'],
|
|
47
|
-
sources: item['sources'].map { |s| format_source(s) }
|
|
48
|
-
}
|
|
49
|
-
end
|
|
50
43
|
end
|
|
51
44
|
end
|
|
52
45
|
end
|
|
@@ -52,36 +52,74 @@ module Sumologic
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def perform_search
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
if aggregate_mode?
|
|
56
|
+
client.search_aggregation(
|
|
57
|
+
query: options[:query],
|
|
58
|
+
from_time: @parsed_from,
|
|
59
|
+
to_time: @parsed_to,
|
|
60
|
+
time_zone: @parsed_timezone,
|
|
61
|
+
limit: options[:limit]
|
|
62
|
+
)
|
|
63
|
+
else
|
|
64
|
+
client.search(
|
|
65
|
+
query: options[:query],
|
|
66
|
+
from_time: @parsed_from,
|
|
67
|
+
to_time: @parsed_to,
|
|
68
|
+
time_zone: @parsed_timezone,
|
|
69
|
+
limit: options[:limit]
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def aggregate_mode?
|
|
75
|
+
options[:aggregate] || aggregation_query?(options[:query])
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def aggregation_query?(query)
|
|
79
|
+
query.match?(/\|\s*(count|sum|avg|min|max|pct|first|last|group)\b/i)
|
|
62
80
|
end
|
|
63
81
|
|
|
64
82
|
def display_results_summary(results)
|
|
83
|
+
result_type = aggregate_mode? ? 'records' : 'messages'
|
|
65
84
|
warn '=' * 60
|
|
66
|
-
warn "Results: #{results.size}
|
|
85
|
+
warn "Results: #{results.size} #{result_type}"
|
|
67
86
|
warn '=' * 60
|
|
68
87
|
$stderr.puts
|
|
69
88
|
end
|
|
70
89
|
|
|
71
90
|
def output_search_results(results)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
if aggregate_mode?
|
|
92
|
+
output_json(
|
|
93
|
+
query: options[:query],
|
|
94
|
+
from: @parsed_from,
|
|
95
|
+
to: @parsed_to,
|
|
96
|
+
from_original: @original_from,
|
|
97
|
+
to_original: @original_to,
|
|
98
|
+
time_zone: @parsed_timezone,
|
|
99
|
+
record_count: results.size,
|
|
100
|
+
records: results
|
|
101
|
+
)
|
|
102
|
+
else
|
|
103
|
+
output_json(
|
|
104
|
+
query: options[:query],
|
|
105
|
+
from: @parsed_from,
|
|
106
|
+
to: @parsed_to,
|
|
107
|
+
from_original: @original_from,
|
|
108
|
+
to_original: @original_to,
|
|
109
|
+
time_zone: @parsed_timezone,
|
|
110
|
+
message_count: results.size,
|
|
111
|
+
messages: results
|
|
112
|
+
)
|
|
113
|
+
end
|
|
82
114
|
end
|
|
83
115
|
|
|
84
116
|
def launch_interactive_mode(results)
|
|
117
|
+
if aggregate_mode?
|
|
118
|
+
warn 'Interactive mode is not supported for aggregation queries'
|
|
119
|
+
output_search_results(results)
|
|
120
|
+
return
|
|
121
|
+
end
|
|
122
|
+
|
|
85
123
|
require_relative '../../interactive'
|
|
86
124
|
|
|
87
125
|
formatted_results = build_formatted_results(results)
|