awsutils 2.1.2 → 2.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b349fef53bb0e69ba94c897c44395410dba6710
4
- data.tar.gz: e1e33dfd6b6c52810309e0b33304268495521ec2
3
+ metadata.gz: 95f34da34fad24fe442ee18a0b59ba3b6785e6b8
4
+ data.tar.gz: f809b1fdee1e38c522ecfd888da1497e20c01d54
5
5
  SHA512:
6
- metadata.gz: ef0b74c2dbbc588ff444ce4f2993cacc71fbb436889bd0f1cc0a82be835e8db2aeba32eac11d5bf6500811cccfc8e1094efc29e1f6e489a325a429725d83282f
7
- data.tar.gz: ee242a063408d1712c690fa1d8329c55f692789da9d737945213fd891652e35d8f258c5f3710973304d16a6d60c884af65f96eea08c52919ef5bbb6143381b3d
6
+ metadata.gz: 0653f177362210ad4875cc64bb1722bac7f0095041c8e2c219779e6873141eff533bd45af70d0fff93f7d9b405dbdbaf02c7862f86efd346bd6c1e10f3f333ec
7
+ data.tar.gz: ce754a5256133a11d5a3ca311af86ee4a2c2990af2a88272b06f00ce136b7824b981e67554c4b4d374922795b7bd31c631246fe644c928db03fbe9a92b5e51a3
@@ -0,0 +1,5 @@
1
+ LineLength:
2
+ Max: 100
3
+
4
+ MethodLength:
5
+ Max: 50
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_dependency 'facets', '~> 2.9'
30
30
  spec.add_dependency 'rainbow', '~> 2.0'
31
- spec.add_dependency 'fog-aws', '~> 0.10.0'
31
+ spec.add_dependency 'fog-aws', '~> 0.11.0'
32
32
  spec.add_dependency 'trollop'
33
33
  spec.add_dependency 'aws-sdk'
34
34
  end
@@ -10,5 +10,4 @@
10
10
  require 'awsutils/version'
11
11
  require 'awsutils/awslogs'
12
12
 
13
- awslogs = AwsUtils::AwsLogs.new
14
- awslogs.print_events
13
+ AwsUtils::AwsLogs.new.run
@@ -2,23 +2,59 @@ require 'trollop'
2
2
  require 'aws-sdk'
3
3
  require 'time'
4
4
 
5
+ class LogGroupNotFoundError < StandardError; end
6
+ class MultipleGroupsError < StandardError; end
7
+ class TooManyEventsError < StandardError; end
8
+ class TooManyStreamsError < StandardError; end
9
+ class NoStreamsError < StandardError; end
10
+
5
11
  module AwsUtils
6
12
  class AwsLogs
7
13
  LOG_LEVELS = %w(TRACE DEBUG INFO NOTICE WARNING ERROR FATAL).freeze
14
+ MAX_EVENTS = 100000.freeze
15
+ MAX_STREAMS = 100.freeze
16
+
17
+ def run
18
+ print_events
19
+ rescue TooManyEventsError
20
+ puts "Too many log events to process (MAX: #{MAX_EVENTS}). " \
21
+ 'Please try filtering the output with -f'
22
+ exit 3
23
+ rescue TooManyStreamsError
24
+ puts "Too many streams to process (MAX: #{MAX_STREAMS}). " \
25
+ 'Please try filtering the output with -s'
26
+ exit 3
27
+ rescue LogGroupNotFoundError
28
+ puts "No log groups found starting with #{opts[:group]}"
29
+ exit 1
30
+ rescue NoStreamsError
31
+ puts 'Streams filter did not return any streams'
32
+ exit 1
33
+ rescue MultipleGroupsError => e
34
+ puts e.message
35
+ exit 2
36
+ end
37
+
38
+ private
8
39
 
9
40
  def opts
10
41
  @opts ||= Trollop.options do
42
+ opt :age,
43
+ 'Max age in seconds',
44
+ short: 'a',
45
+ type: Integer
11
46
  opt :group,
12
47
  'Log group (e.g. /aws/lambda/sf-updater)',
13
48
  required: true,
14
- type: :string,
49
+ type: String,
15
50
  short: 'g'
16
51
  opt :filter_pattern,
17
52
  'See: http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/FilterAndPatternSyntax.html',
53
+ type: String,
18
54
  short: 'f'
19
55
  opt :streams_prefix,
20
56
  'E.g. 2016/08',
21
- default: Time.now.strftime('%Y/%m/%d'),
57
+ type: String,
22
58
  short: 's'
23
59
  opt :timestamp,
24
60
  'Include the timestamp from the event metadata in the output',
@@ -42,16 +78,30 @@ module AwsUtils
42
78
  end
43
79
  end
44
80
 
81
+ def log_group_name
82
+ @log_group ||= begin
83
+ r = cloudwatchlogs.describe_log_groups log_group_name_prefix: opts[:group]
84
+ return r.log_groups.first.log_group_name if r.log_groups.count == 1
85
+ raise LogGroupNotFoundError if r.log_groups.empty?
86
+ err_msg = "Group filter #{opts[:group]} found multiple groups:\n\n"
87
+ err_msg += r.log_groups.map(&:log_group_name).join("\n")
88
+ err_msg += "\nMore than 50 log groups returned. Only showed the first 50." if r.next_token
89
+ raise MultipleGroupsError, err_msg
90
+ end
91
+ end
92
+
45
93
  def chunk_events(streams_chunk, token = nil)
46
94
  parameters = {
47
- log_group_name: opts[:group],
95
+ log_group_name: log_group_name,
48
96
  log_stream_names: streams_chunk,
97
+ start_time: max_age_ts,
49
98
  next_token: token
50
99
  }
51
100
  parameters[:filter_pattern] = opts[:filter_pattern] if opts[:filter_pattern]
52
101
  response = cloudwatchlogs.filter_log_events parameters
53
102
  collector = response.events
54
103
  collector += chunk_events(streams_chunk, response.next_token) if response.next_token
104
+ raise TooManyEventsError if collector.count > MAX_EVENTS
55
105
  collector
56
106
  end
57
107
 
@@ -76,6 +126,7 @@ module AwsUtils
76
126
  print "#{ev.log_stream_name}: " if opts[:show_stream_name]
77
127
  print Time.at(ev.timestamp / 1e3).iso8601(3) + ' ' if opts[:timestamp]
78
128
  print ev.message
129
+ print "\n" if ev.message[-1] != "\n"
79
130
  next
80
131
  end
81
132
 
@@ -101,16 +152,28 @@ module AwsUtils
101
152
  end
102
153
 
103
154
  def streams(token = nil)
104
- response = cloudwatchlogs.describe_log_streams(
105
- log_group_name: opts[:group],
106
- log_stream_name_prefix: opts[:streams_prefix],
155
+ parameters = {
156
+ log_group_name: log_group_name,
107
157
  next_token: token
108
- )
109
- collector = response.log_streams.map(&:log_stream_name)
158
+ }
159
+ parameters[:log_stream_name_prefix] = opts[:streams_prefix] if opts[:streams_prefix]
160
+ response = cloudwatchlogs.describe_log_streams parameters
161
+ collector =
162
+ response
163
+ .log_streams
164
+ .select { |s| s.last_event_timestamp && s.last_event_timestamp > max_age_ts }
165
+ .map(&:log_stream_name)
166
+ fail NoStreamsError if token.nil? && collector.count == 0
110
167
  collector += streams(response.next_token) if response.next_token
168
+ fail TooManyStreamsError if collector.count > MAX_STREAMS
111
169
  collector
112
170
  end
113
171
 
172
+ def max_age_ts
173
+ return 0 unless opts[:age]
174
+ (Time.at(Time.now - opts[:age]).to_f * 1_000).to_i
175
+ end
176
+
114
177
  def cloudwatchlogs
115
178
  @cloudwatchlogs ||= Aws::CloudWatchLogs::Client.new
116
179
  end
@@ -1,3 +1,3 @@
1
1
  module AwsUtils
2
- VERSION = '2.1.2'
2
+ VERSION = '2.1.6'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awsutils
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Herot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-24 00:00:00.000000000 Z
11
+ date: 2016-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 0.10.0
145
+ version: 0.11.0
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 0.10.0
152
+ version: 0.11.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: trollop
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -195,6 +195,7 @@ extensions: []
195
195
  extra_rdoc_files: []
196
196
  files:
197
197
  - ".gitignore"
198
+ - ".rubocop.yml"
198
199
  - Gemfile
199
200
  - LICENSE.txt
200
201
  - README.md
@@ -245,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
246
  version: '0'
246
247
  requirements: []
247
248
  rubyforge_project:
248
- rubygems_version: 2.4.5
249
+ rubygems_version: 2.5.1
249
250
  signing_key:
250
251
  specification_version: 4
251
252
  summary: A set of tools for interacting with AWS (summary)