sumologic-query 1.3.3 → 1.3.5
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 +34 -0
- data/README.md +88 -231
- data/lib/sumologic/cli/commands/base_command.rb +6 -0
- data/lib/sumologic/cli/commands/discover_sources_command.rb +59 -0
- data/lib/sumologic/cli/commands/search_command.rb +29 -10
- data/lib/sumologic/cli.rb +62 -9
- data/lib/sumologic/client.rb +23 -1
- data/lib/sumologic/configuration.rb +5 -1
- data/lib/sumologic/http/client.rb +1 -1
- data/lib/sumologic/http/debug_logger.rb +2 -1
- data/lib/sumologic/metadata/collector.rb +5 -6
- data/lib/sumologic/metadata/collector_source_fetcher.rb +7 -3
- data/lib/sumologic/metadata/dynamic_source_discovery.rb +155 -0
- data/lib/sumologic/metadata/loggable.rb +32 -0
- data/lib/sumologic/metadata/models.rb +108 -0
- data/lib/sumologic/metadata/source.rb +13 -18
- data/lib/sumologic/search/job.rb +17 -1
- data/lib/sumologic/search/message_fetcher.rb +4 -1
- data/lib/sumologic/search/record_fetcher.rb +125 -0
- data/lib/sumologic/utils/time_parser.rb +147 -0
- data/lib/sumologic/utils/worker.rb +18 -4
- data/lib/sumologic/version.rb +1 -1
- data/lib/sumologic.rb +4 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 83e78d35f43a7e12f98e3ed11d9d4b0ddd7fe4cf567c281fa4729c8873c583a0
|
|
4
|
+
data.tar.gz: 4cc242bc523b5ce0cf709ec9f9aceb44cb1fe5911582983ae80e3a49d00a175d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b9d63d998ff14e1b9db86dc982dd84b508f642c01a62883b7bdce997ec21aed3097477956776319f01b68da2e8ed967b713894ed8002353ab99ee9fd72bad85
|
|
7
|
+
data.tar.gz: '084c1c7db713d88f88979941d8b6a261f48c4bc533f3ce2ac04cb97ea3bae5fb0762889611dbfffd790740e0c7928acffb9e7df144c6e6d7b0fa129128d49e23'
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,40 @@ 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.3.5](https://github.com/patrick204nqh/sumologic-query/compare/v1.3.4...v1.3.5) (2025-11-19)
|
|
10
|
+
|
|
11
|
+
### 🎉 New Features
|
|
12
|
+
|
|
13
|
+
- add discover-sources command for dynamic source discovery from logs
|
|
14
|
+
- implement rate limiting configuration and enhance documentation for querying options
|
|
15
|
+
|
|
16
|
+
### 🔧 Refactoring
|
|
17
|
+
|
|
18
|
+
- improve source discovery logic and enhance debugging output
|
|
19
|
+
|
|
20
|
+
### 📚 Documentation
|
|
21
|
+
|
|
22
|
+
- update tldr.md with enhanced search options and new commands for querying logs
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## [1.3.4](https://github.com/patrick204nqh/sumologic-query/compare/v1.3.3...v1.3.4) (2025-11-19)
|
|
27
|
+
|
|
28
|
+
### 🎉 New Features
|
|
29
|
+
|
|
30
|
+
- add time parsing utility and enhance CLI time options for flexible querying
|
|
31
|
+
- enhance debug logging to include request headers for better traceability
|
|
32
|
+
|
|
33
|
+
### 🐛 Bug Fixes
|
|
34
|
+
|
|
35
|
+
- freeze regex for relative time parsing and improve error message formatting
|
|
36
|
+
|
|
37
|
+
### 📚 Documentation
|
|
38
|
+
|
|
39
|
+
- update README and examples to enhance time format usage and add new time format examples
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
9
43
|
## [1.3.3](https://github.com/patrick204nqh/sumologic-query/compare/v1.3.2...v1.3.3) (2025-11-17)
|
|
10
44
|
|
|
11
45
|
### 🎉 New Features
|
data/README.md
CHANGED
|
@@ -6,309 +6,166 @@
|
|
|
6
6
|
[](https://rubygems.org/gems/sumologic-query)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Features
|
|
10
10
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
|
|
18
|
-
All existing Ruby Sumo Logic gems are unmaintained (2-9 years dormant). This tool provides a fresh, minimal approach focused on querying logs and metadata.
|
|
11
|
+
- **Simple time parsing** - Use `-1h`, `-30m`, `now` instead of timestamps
|
|
12
|
+
- **Dynamic source discovery** - Find CloudWatch/ECS/Lambda sources from logs
|
|
13
|
+
- **Interactive mode** - Explore logs with FZF fuzzy search
|
|
14
|
+
- **Timezone support** - US, Australian, and IANA formats
|
|
15
|
+
- **Fast & efficient** - Smart polling and pagination
|
|
16
|
+
- **Read-only** - Safe log access with no write operations
|
|
19
17
|
|
|
20
18
|
## Installation
|
|
21
19
|
|
|
22
|
-
### Via RubyGems
|
|
23
|
-
|
|
24
20
|
```bash
|
|
21
|
+
# Via RubyGems
|
|
25
22
|
gem install sumologic-query
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Via Homebrew
|
|
29
23
|
|
|
30
|
-
|
|
24
|
+
# Via Homebrew
|
|
31
25
|
brew tap patrick204nqh/tap
|
|
32
26
|
brew install sumologic-query
|
|
33
27
|
```
|
|
34
28
|
|
|
35
|
-
### From Source
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
git clone https://github.com/patrick204nqh/sumologic-query.git
|
|
39
|
-
cd sumologic-query
|
|
40
|
-
bundle install
|
|
41
|
-
bundle exec rake install
|
|
42
|
-
```
|
|
43
|
-
|
|
44
29
|
## Quick Start
|
|
45
30
|
|
|
46
|
-
### 1. Set
|
|
47
|
-
|
|
48
|
-
Export your Sumo Logic API credentials:
|
|
31
|
+
### 1. Set Credentials
|
|
49
32
|
|
|
50
33
|
```bash
|
|
51
34
|
export SUMO_ACCESS_ID="your_access_id"
|
|
52
35
|
export SUMO_ACCESS_KEY="your_access_key"
|
|
53
|
-
export SUMO_DEPLOYMENT="us2" # Optional: us1, us2 (default), eu, au
|
|
36
|
+
export SUMO_DEPLOYMENT="us2" # Optional: us1, us2 (default), eu, au
|
|
54
37
|
```
|
|
55
38
|
|
|
56
|
-
**
|
|
57
|
-
1. Log in to Sumo Logic
|
|
58
|
-
2. Go to **Administration → Security → Access Keys**
|
|
59
|
-
3. Create a new access key or use existing
|
|
60
|
-
4. Copy the Access ID and Access Key
|
|
39
|
+
Get credentials: Sumo Logic → **Administration → Security → Access Keys**
|
|
61
40
|
|
|
62
|
-
### 2. Run
|
|
41
|
+
### 2. Run Queries
|
|
63
42
|
|
|
64
43
|
```bash
|
|
65
44
|
# Search logs
|
|
66
|
-
sumo-query search
|
|
67
|
-
--from '2025-11-13T14:00:00' \
|
|
68
|
-
--to '2025-11-13T15:00:00' \
|
|
69
|
-
--limit 10
|
|
45
|
+
sumo-query search -q 'error' -f '-1h' -t 'now' --limit 100
|
|
70
46
|
|
|
71
|
-
#
|
|
72
|
-
sumo-query
|
|
47
|
+
# Discover dynamic sources (CloudWatch/ECS/Lambda)
|
|
48
|
+
sumo-query discover-sources
|
|
73
49
|
|
|
74
|
-
# List sources
|
|
50
|
+
# List collectors and sources
|
|
51
|
+
sumo-query collectors
|
|
75
52
|
sumo-query sources
|
|
76
53
|
```
|
|
77
54
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
The CLI provides three main commands:
|
|
55
|
+
## Commands
|
|
81
56
|
|
|
82
|
-
### Search Logs
|
|
57
|
+
### 1. Search Logs
|
|
83
58
|
|
|
84
59
|
```bash
|
|
85
|
-
sumo-query search
|
|
86
|
-
--from "START_TIME" \
|
|
87
|
-
--to "END_TIME" \
|
|
88
|
-
[--output FILE] \
|
|
89
|
-
[--limit N] \
|
|
90
|
-
[--time-zone TZ] \
|
|
91
|
-
[--interactive]
|
|
60
|
+
sumo-query search -q "YOUR_QUERY" -f "START" -t "END" [OPTIONS]
|
|
92
61
|
```
|
|
93
62
|
|
|
94
|
-
**
|
|
95
|
-
- `-q, --query
|
|
96
|
-
- `-f, --from
|
|
97
|
-
- `-t, --to
|
|
63
|
+
**Options:**
|
|
64
|
+
- `-q, --query` - Query string (required)
|
|
65
|
+
- `-f, --from` - Start time (required, e.g., `-1h`, `2025-11-19T14:00:00`)
|
|
66
|
+
- `-t, --to` - End time (required, e.g., `now`)
|
|
67
|
+
- `-z, --time-zone` - Timezone (default: UTC)
|
|
68
|
+
- `-l, --limit` - Max messages to return
|
|
69
|
+
- `-o, --output` - Save to file
|
|
70
|
+
- `-i, --interactive` - Launch FZF browser
|
|
71
|
+
- `-d, --debug` - Debug output
|
|
98
72
|
|
|
99
|
-
**
|
|
100
|
-
- `-i, --interactive` - Launch interactive browser with FZF
|
|
101
|
-
- `-z, --time-zone TZ` - Time zone (default: UTC)
|
|
102
|
-
- `-l, --limit N` - Limit number of messages
|
|
103
|
-
- `-o, --output FILE` - Save to file (default: stdout)
|
|
104
|
-
- `-d, --debug` - Enable debug output
|
|
73
|
+
**Interactive Mode** (`-i`): FZF-based browser with fuzzy search, preview, and multi-select. Requires `fzf` ([install](https://github.com/junegunn/fzf#installation)).
|
|
105
74
|
|
|
106
|
-
###
|
|
107
|
-
|
|
108
|
-
Explore your logs interactively with a powerful FZF-based interface:
|
|
75
|
+
### 2. Discover Dynamic Sources
|
|
109
76
|
|
|
110
77
|
```bash
|
|
111
|
-
|
|
112
|
-
sumo-query search --query 'error' \
|
|
113
|
-
--from '2025-11-13T14:00:00' \
|
|
114
|
-
--to '2025-11-13T15:00:00' \
|
|
115
|
-
--interactive
|
|
116
|
-
|
|
117
|
-
# Or use the shorthand
|
|
118
|
-
sumo-query search -q 'error' -f '2025-11-13T14:00:00' -t '2025-11-13T15:00:00' -i
|
|
78
|
+
sumo-query discover-sources [OPTIONS]
|
|
119
79
|
```
|
|
120
80
|
|
|
121
|
-
|
|
122
|
-
- 🔍 Fuzzy search across all message fields
|
|
123
|
-
- 👁️ Live preview with full JSON details
|
|
124
|
-
- 🎨 Color-coded log levels (ERROR, WARN, INFO)
|
|
125
|
-
- ⌨️ Keyboard shortcuts for quick actions
|
|
126
|
-
- 📋 Multi-select and batch operations
|
|
127
|
-
- 💾 Export selected messages
|
|
128
|
-
|
|
129
|
-
**Keybindings:**
|
|
130
|
-
- `Enter` - Toggle selection (mark/unmark message)
|
|
131
|
-
- `Tab` - Open current message in pager (copyable view)
|
|
132
|
-
- `Ctrl-S` - Save selected messages to `sumo-selected.txt` and exit
|
|
133
|
-
- `Ctrl-Y` - Copy selected messages to clipboard and exit
|
|
134
|
-
- `Ctrl-E` - Export selected messages to `sumo-export.jsonl` and exit
|
|
135
|
-
- `Ctrl-A` - Select all messages
|
|
136
|
-
- `Ctrl-D` - Deselect all messages
|
|
137
|
-
- `Ctrl-/` - Toggle preview pane
|
|
138
|
-
- `Ctrl-Q` - Quit without saving
|
|
139
|
-
|
|
140
|
-
**Requirements:**
|
|
141
|
-
- Install FZF: `brew install fzf` (macOS) or `apt-get install fzf` (Linux)
|
|
142
|
-
- See: https://github.com/junegunn/fzf#installation
|
|
143
|
-
|
|
144
|
-
### List Collectors
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
sumo-query collectors [--output FILE]
|
|
148
|
-
```
|
|
81
|
+
Finds dynamic source names from log data (CloudWatch, ECS, Lambda streams).
|
|
149
82
|
|
|
150
|
-
|
|
83
|
+
**Options:**
|
|
84
|
+
- `-f, --from` - Start time (default: `-24h`)
|
|
85
|
+
- `-t, --to` - End time (default: `now`)
|
|
86
|
+
- `--filter` - Filter query (e.g., `_sourceCategory=*ecs*`)
|
|
87
|
+
- `-z, --time-zone` - Timezone (default: UTC)
|
|
88
|
+
- `-o, --output` - Save to file
|
|
151
89
|
|
|
152
|
-
|
|
90
|
+
**Examples:**
|
|
153
91
|
|
|
154
92
|
```bash
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
Lists all sources from active collectors.
|
|
159
|
-
|
|
160
|
-
**See [examples/queries.md](examples/queries.md) for more query patterns and examples.**
|
|
93
|
+
# Discover all sources from last 24 hours
|
|
94
|
+
sumo-query discover-sources
|
|
161
95
|
|
|
162
|
-
|
|
96
|
+
# Filter to ECS only
|
|
97
|
+
sumo-query discover-sources --filter '_sourceCategory=*ecs*'
|
|
163
98
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
require 'sumologic'
|
|
168
|
-
|
|
169
|
-
# Initialize client
|
|
170
|
-
client = Sumologic::Client.new(
|
|
171
|
-
access_id: ENV['SUMO_ACCESS_ID'],
|
|
172
|
-
access_key: ENV['SUMO_ACCESS_KEY'],
|
|
173
|
-
deployment: 'us2'
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
# Search logs
|
|
177
|
-
results = client.search(
|
|
178
|
-
query: 'error',
|
|
179
|
-
from_time: '2025-11-13T14:00:00',
|
|
180
|
-
to_time: '2025-11-13T15:00:00',
|
|
181
|
-
time_zone: 'UTC',
|
|
182
|
-
limit: 1000
|
|
183
|
-
)
|
|
99
|
+
# Last 7 days, save to file
|
|
100
|
+
sumo-query discover-sources -f '-7d' -o sources.json
|
|
101
|
+
```
|
|
184
102
|
|
|
185
|
-
|
|
186
|
-
puts message['map']['message']
|
|
187
|
-
end
|
|
103
|
+
### 3. List Collectors & Sources
|
|
188
104
|
|
|
105
|
+
```bash
|
|
189
106
|
# List collectors
|
|
190
|
-
collectors
|
|
107
|
+
sumo-query collectors [-o FILE]
|
|
191
108
|
|
|
192
|
-
# List
|
|
193
|
-
sources
|
|
109
|
+
# List static sources
|
|
110
|
+
sumo-query sources [-o FILE]
|
|
194
111
|
```
|
|
195
112
|
|
|
196
|
-
**See [docs/api-reference.md](docs/api-reference.md) for complete API documentation.**
|
|
197
|
-
|
|
198
113
|
## Time Formats
|
|
199
114
|
|
|
200
|
-
Use ISO 8601 format for timestamps:
|
|
201
|
-
|
|
202
115
|
```bash
|
|
203
|
-
#
|
|
204
|
-
|
|
116
|
+
# Relative (recommended)
|
|
117
|
+
-1h, -30m, -7d, now
|
|
205
118
|
|
|
206
|
-
#
|
|
207
|
-
|
|
119
|
+
# ISO 8601
|
|
120
|
+
2025-11-19T14:00:00
|
|
208
121
|
|
|
209
|
-
#
|
|
210
|
-
|
|
211
|
-
--to "$(date -u '+%Y-%m-%dT%H:%M:%S')" # now
|
|
212
|
-
```
|
|
122
|
+
# Unix timestamp
|
|
123
|
+
1700000000
|
|
213
124
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
Results are returned as JSON:
|
|
217
|
-
|
|
218
|
-
```json
|
|
219
|
-
{
|
|
220
|
-
"query": "error",
|
|
221
|
-
"from": "2025-11-13T14:00:00",
|
|
222
|
-
"to": "2025-11-13T15:00:00",
|
|
223
|
-
"time_zone": "UTC",
|
|
224
|
-
"message_count": 42,
|
|
225
|
-
"messages": [
|
|
226
|
-
{
|
|
227
|
-
"map": {
|
|
228
|
-
"_messagetime": "1731506400123",
|
|
229
|
-
"_sourceCategory": "prod/api",
|
|
230
|
-
"_sourceName": "api-server-01",
|
|
231
|
-
"message": "Error processing request: timeout"
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
]
|
|
235
|
-
}
|
|
125
|
+
# Timezones
|
|
126
|
+
UTC, AEST, EST, America/New_York, Australia/Sydney, +10:00
|
|
236
127
|
```
|
|
237
128
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Query execution time depends on data volume:
|
|
129
|
+
See [examples/queries.md](examples/queries.md) for comprehensive query patterns.
|
|
241
130
|
|
|
242
|
-
|
|
243
|
-
|----------|--------------|
|
|
244
|
-
| < 10K | 30-60 seconds |
|
|
245
|
-
| 10K-100K | 1-2 minutes |
|
|
246
|
-
| 100K+ | 2-5 minutes |
|
|
131
|
+
## Ruby Library
|
|
247
132
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
- Add `_sourceCategory` filters
|
|
251
|
-
- Use `--limit` to cap results
|
|
252
|
-
- Use aggregation queries instead of raw messages
|
|
253
|
-
|
|
254
|
-
## Documentation
|
|
255
|
-
|
|
256
|
-
- **[Quick Reference (tldr)](docs/tldr.md)** - Concise command examples in tldr format
|
|
257
|
-
- **[Query Examples](examples/queries.md)** - Common query patterns and use cases
|
|
258
|
-
- **[API Reference](docs/api-reference.md)** - Complete Ruby library documentation
|
|
259
|
-
- **[Architecture](docs/architecture/)** - System design and architecture decisions
|
|
260
|
-
- **[Troubleshooting](docs/troubleshooting.md)** - Common issues and solutions
|
|
261
|
-
|
|
262
|
-
## Development
|
|
133
|
+
```ruby
|
|
134
|
+
require 'sumologic'
|
|
263
135
|
|
|
264
|
-
|
|
136
|
+
client = Sumologic::Client.new(
|
|
137
|
+
access_id: ENV['SUMO_ACCESS_ID'],
|
|
138
|
+
access_key: ENV['SUMO_ACCESS_KEY']
|
|
139
|
+
)
|
|
265
140
|
|
|
266
|
-
|
|
141
|
+
# Search
|
|
142
|
+
client.search(query: 'error', from_time: '-1h', to_time: 'now')
|
|
267
143
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
git clone https://github.com/patrick204nqh/sumologic-query.git
|
|
271
|
-
cd sumologic-query
|
|
272
|
-
bundle install
|
|
144
|
+
# Discover sources
|
|
145
|
+
client.discover_dynamic_sources(from_time: '-24h', to_time: 'now')
|
|
273
146
|
|
|
274
|
-
#
|
|
275
|
-
|
|
147
|
+
# Metadata
|
|
148
|
+
client.list_collectors
|
|
149
|
+
client.list_all_sources
|
|
150
|
+
```
|
|
276
151
|
|
|
277
|
-
|
|
278
|
-
bundle exec rubocop
|
|
152
|
+
## Documentation
|
|
279
153
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
```
|
|
154
|
+
- [Query Examples](examples/queries.md) - Query patterns and examples
|
|
155
|
+
- [Quick Reference](docs/tldr.md) - Command cheat sheet
|
|
156
|
+
- [Rate Limiting](docs/rate-limiting.md) - Performance tuning
|
|
157
|
+
- [Architecture](docs/architecture/) - Design decisions
|
|
285
158
|
|
|
286
159
|
## Contributing
|
|
287
160
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
1. Fork the repository
|
|
291
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
292
|
-
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
293
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
294
|
-
5. Open a Pull Request
|
|
161
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
295
162
|
|
|
296
163
|
## License
|
|
297
164
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
## Support
|
|
301
|
-
|
|
302
|
-
- **Issues**: [GitHub Issues](https://github.com/patrick204nqh/sumologic-query/issues)
|
|
303
|
-
- **Discussions**: [GitHub Discussions](https://github.com/patrick204nqh/sumologic-query/discussions)
|
|
304
|
-
- **Documentation**: [docs/](docs/)
|
|
305
|
-
|
|
306
|
-
## Resources
|
|
307
|
-
|
|
308
|
-
- **Sumo Logic API Docs**: https://help.sumologic.com/docs/api/search-job/
|
|
309
|
-
- **Query Language**: https://help.sumologic.com/docs/search/
|
|
310
|
-
- **Bug Reports**: https://github.com/patrick204nqh/sumologic-query/issues
|
|
165
|
+
MIT License - see [LICENSE](LICENSE) file.
|
|
311
166
|
|
|
312
|
-
|
|
167
|
+
## Links
|
|
313
168
|
|
|
314
|
-
|
|
169
|
+
- [Issues](https://github.com/patrick204nqh/sumologic-query/issues)
|
|
170
|
+
- [Sumo Logic API Docs](https://help.sumologic.com/docs/api/search-job/)
|
|
171
|
+
- [Query Language](https://help.sumologic.com/docs/search/)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
3
5
|
module Sumologic
|
|
4
6
|
class CLI < Thor
|
|
5
7
|
module Commands
|
|
@@ -19,6 +21,10 @@ module Sumologic
|
|
|
19
21
|
json_output = JSON.pretty_generate(data)
|
|
20
22
|
|
|
21
23
|
if options[:output]
|
|
24
|
+
# Create parent directories if they don't exist
|
|
25
|
+
output_dir = File.dirname(options[:output])
|
|
26
|
+
FileUtils.mkdir_p(output_dir) unless output_dir == '.'
|
|
27
|
+
|
|
22
28
|
File.write(options[:output], json_output)
|
|
23
29
|
warn "\nResults saved to: #{options[:output]}"
|
|
24
30
|
else
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base_command'
|
|
4
|
+
require_relative '../../utils/time_parser'
|
|
5
|
+
|
|
6
|
+
module Sumologic
|
|
7
|
+
class CLI < Thor
|
|
8
|
+
module Commands
|
|
9
|
+
# Handles the discover-sources command execution
|
|
10
|
+
class DiscoverSourcesCommand < BaseCommand
|
|
11
|
+
def execute
|
|
12
|
+
parse_time_options
|
|
13
|
+
log_discovery_info
|
|
14
|
+
results = perform_discovery
|
|
15
|
+
|
|
16
|
+
output_json(results)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def parse_time_options
|
|
22
|
+
# Parse time formats and store both original and parsed values
|
|
23
|
+
@original_from = options[:from]
|
|
24
|
+
@original_to = options[:to]
|
|
25
|
+
@parsed_from = Utils::TimeParser.parse(options[:from])
|
|
26
|
+
@parsed_to = Utils::TimeParser.parse(options[:to])
|
|
27
|
+
@parsed_timezone = Utils::TimeParser.parse_timezone(options[:time_zone])
|
|
28
|
+
rescue Utils::TimeParser::ParseError => e
|
|
29
|
+
warn "Error parsing time: #{e.message}"
|
|
30
|
+
exit 1
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def log_discovery_info
|
|
34
|
+
warn '=' * 60
|
|
35
|
+
warn 'Discovering Dynamic Source Names'
|
|
36
|
+
warn '=' * 60
|
|
37
|
+
warn "Time Range: #{@original_from} to #{@original_to}"
|
|
38
|
+
if @original_from != @parsed_from || @original_to != @parsed_to
|
|
39
|
+
warn " (Parsed: #{@parsed_from} to #{@parsed_to})"
|
|
40
|
+
end
|
|
41
|
+
warn "Time Zone: #{@parsed_timezone}"
|
|
42
|
+
warn "Filter: #{options[:filter] || 'none (all sources)'}"
|
|
43
|
+
warn '-' * 60
|
|
44
|
+
warn 'Running aggregation query to discover sources...'
|
|
45
|
+
$stderr.puts
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def perform_discovery
|
|
49
|
+
client.discover_dynamic_sources(
|
|
50
|
+
from_time: @parsed_from,
|
|
51
|
+
to_time: @parsed_to,
|
|
52
|
+
time_zone: @parsed_timezone,
|
|
53
|
+
filter: options[:filter]
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'base_command'
|
|
4
|
+
require_relative '../../utils/time_parser'
|
|
4
5
|
|
|
5
6
|
module Sumologic
|
|
6
7
|
class CLI < Thor
|
|
@@ -8,6 +9,7 @@ module Sumologic
|
|
|
8
9
|
# Handles the search command execution
|
|
9
10
|
class SearchCommand < BaseCommand
|
|
10
11
|
def execute
|
|
12
|
+
parse_time_options
|
|
11
13
|
log_search_info
|
|
12
14
|
results = perform_search
|
|
13
15
|
|
|
@@ -22,11 +24,26 @@ module Sumologic
|
|
|
22
24
|
|
|
23
25
|
private
|
|
24
26
|
|
|
27
|
+
def parse_time_options
|
|
28
|
+
# Parse time formats and store both original and parsed values
|
|
29
|
+
@original_from = options[:from]
|
|
30
|
+
@original_to = options[:to]
|
|
31
|
+
@parsed_from = Utils::TimeParser.parse(options[:from])
|
|
32
|
+
@parsed_to = Utils::TimeParser.parse(options[:to])
|
|
33
|
+
@parsed_timezone = Utils::TimeParser.parse_timezone(options[:time_zone])
|
|
34
|
+
rescue Utils::TimeParser::ParseError => e
|
|
35
|
+
warn "Error parsing time: #{e.message}"
|
|
36
|
+
exit 1
|
|
37
|
+
end
|
|
38
|
+
|
|
25
39
|
def log_search_info
|
|
26
40
|
warn '=' * 60
|
|
27
41
|
warn 'Sumo Logic Search Query'
|
|
28
42
|
warn '=' * 60
|
|
29
|
-
warn "Time Range: #{
|
|
43
|
+
warn "Time Range: #{@original_from} to #{@original_to}"
|
|
44
|
+
if @original_from != @parsed_from || @original_to != @parsed_to
|
|
45
|
+
warn " (Parsed: #{@parsed_from} to #{@parsed_to})"
|
|
46
|
+
end
|
|
30
47
|
warn "Query: #{options[:query]}"
|
|
31
48
|
warn "Limit: #{options[:limit] || 'unlimited'}"
|
|
32
49
|
warn '-' * 60
|
|
@@ -37,9 +54,9 @@ module Sumologic
|
|
|
37
54
|
def perform_search
|
|
38
55
|
client.search(
|
|
39
56
|
query: options[:query],
|
|
40
|
-
from_time:
|
|
41
|
-
to_time:
|
|
42
|
-
time_zone:
|
|
57
|
+
from_time: @parsed_from,
|
|
58
|
+
to_time: @parsed_to,
|
|
59
|
+
time_zone: @parsed_timezone,
|
|
43
60
|
limit: options[:limit]
|
|
44
61
|
)
|
|
45
62
|
end
|
|
@@ -54,9 +71,11 @@ module Sumologic
|
|
|
54
71
|
def output_search_results(results)
|
|
55
72
|
output_json(
|
|
56
73
|
query: options[:query],
|
|
57
|
-
from:
|
|
58
|
-
to:
|
|
59
|
-
|
|
74
|
+
from: @parsed_from,
|
|
75
|
+
to: @parsed_to,
|
|
76
|
+
from_original: @original_from,
|
|
77
|
+
to_original: @original_to,
|
|
78
|
+
time_zone: @parsed_timezone,
|
|
60
79
|
message_count: results.size,
|
|
61
80
|
messages: results
|
|
62
81
|
)
|
|
@@ -75,9 +94,9 @@ module Sumologic
|
|
|
75
94
|
def build_formatted_results(results)
|
|
76
95
|
{
|
|
77
96
|
'query' => options[:query],
|
|
78
|
-
'from' =>
|
|
79
|
-
'to' =>
|
|
80
|
-
'time_zone' =>
|
|
97
|
+
'from' => @parsed_from,
|
|
98
|
+
'to' => @parsed_to,
|
|
99
|
+
'time_zone' => @parsed_timezone,
|
|
81
100
|
'message_count' => results.size,
|
|
82
101
|
'messages' => results
|
|
83
102
|
}
|