11package blade
22
33import (
4+ "context"
45 "encoding/json"
56 "errors"
67 "fmt"
@@ -9,10 +10,9 @@ import (
910
1011 "github.com/TylerBrock/colorjson"
1112 "github.com/TylerBrock/saw/config"
12- "github.com/aws/aws-sdk-go/aws"
13- "github.com/aws/aws-sdk-go/aws/credentials/stscreds"
14- "github.com/aws/aws-sdk-go/aws/session"
15- "github.com/aws/aws-sdk-go/service/cloudwatchlogs"
13+ awsconfig "github.com/aws/aws-sdk-go-v2/config"
14+ "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
15+ "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"
1616 "github.com/fatih/color"
1717)
1818
@@ -21,58 +21,47 @@ type Blade struct {
2121 config * config.Configuration
2222 aws * config.AWSConfiguration
2323 output * config.OutputConfiguration
24- cwl * cloudwatchlogs.CloudWatchLogs
24+ cwl * cloudwatchlogs.Client
2525}
2626
2727// NewBlade creates a new Blade with CloudWatchLogs instance from provided config
2828func NewBlade (
29+ ctx context.Context ,
2930 config * config.Configuration ,
3031 awsConfig * config.AWSConfiguration ,
3132 outputConfig * config.OutputConfiguration ,
32- ) * Blade {
33+ ) ( * Blade , error ) {
3334 blade := Blade {}
34- awsCfg := aws.Config {}
35-
36- if awsConfig .Region != "" {
37- awsCfg .Region = & awsConfig .Region
38- }
39-
40- awsSessionOpts := session.Options {
41- Config : awsCfg ,
42- AssumeRoleTokenProvider : stscreds .StdinTokenProvider ,
43- SharedConfigState : session .SharedConfigEnable ,
44- }
4535
36+ var opts []func (* awsconfig.LoadOptions ) error
4637 if awsConfig .Profile != "" {
47- awsSessionOpts . Profile = awsConfig .Profile
38+ opts = append ( opts , awsconfig . WithSharedConfigProfile ( awsConfig .Profile ))
4839 }
40+ if awsConfig .Region != "" {
41+ opts = append (opts , awsconfig .WithRegion (awsConfig .Region ))
42+ }
43+ awsCfg , err := awsconfig .LoadDefaultConfig (ctx , opts ... )
4944
50- sess := session .Must (session .NewSessionWithOptions (awsSessionOpts ))
51-
52- blade .cwl = cloudwatchlogs .New (sess )
45+ blade .cwl = cloudwatchlogs .NewFromConfig (awsCfg )
5346 blade .config = config
5447 blade .output = outputConfig
5548
56- return & blade
49+ return & blade , err
5750}
5851
5952// GetLogGroups gets the log groups from AWS given the blade configuration
60- func (b * Blade ) GetLogGroups () [] * cloudwatchlogs .LogGroup {
53+ func (b * Blade ) GetLogGroups (ctx context. Context ) ( groups []types .LogGroup , err error ) {
6154 input := b .config .DescribeLogGroupsInput ()
62- groups := make ([]* cloudwatchlogs.LogGroup , 0 )
63- b .cwl .DescribeLogGroupsPages (input , func (
64- out * cloudwatchlogs.DescribeLogGroupsOutput ,
65- lastPage bool ,
66- ) bool {
67- for _ , group := range out .LogGroups {
68- if b .config .Fuzzy && ! groupNameMatches (* group .LogGroupName , b .config .Group ) {
69- continue
70- }
71- groups = append (groups , group )
55+ logGroupsPaginator := cloudwatchlogs .NewDescribeLogGroupsPaginator (b .cwl , input )
56+ var page * cloudwatchlogs.DescribeLogGroupsOutput
57+ for logGroupsPaginator .HasMorePages () {
58+ page , err = logGroupsPaginator .NextPage (ctx )
59+ if err != nil {
60+ return
7261 }
73- return ! lastPage
74- })
75- return groups
62+ groups = append ( groups , page . LogGroups ... )
63+ }
64+ return
7665}
7766
7867func groupNameMatches (s , substr string ) bool {
@@ -117,46 +106,50 @@ func filterGroupNames(groups []*cloudwatchlogs.LogGroup, group string) (op []str
117106}
118107
119108// GetLogStreams gets the log streams from AWS given the blade configuration
120- func (b * Blade ) GetLogStreams () (streams []* cloudwatchlogs .LogStream , err error ) {
109+ func (b * Blade ) GetLogStreams (ctx context. Context ) (streams []types .LogStream , err error ) {
121110 if err := b .ResolveFuzzyGroupName (); err != nil {
122111 return nil , err
123112 }
124113 input := b .config .DescribeLogStreamsInput ()
125- b .cwl . DescribeLogStreamsPages ( input , func (
126- out * cloudwatchlogs.DescribeLogStreamsOutput ,
127- lastPage bool ,
128- ) bool {
129- for _ , stream := range out . LogStreams {
130- streams = append ( streams , stream )
114+ logStreamsPaginator := cloudwatchlogs . NewDescribeLogStreamsPaginator ( b .cwl , input )
115+ var page * cloudwatchlogs.DescribeLogStreamsOutput
116+ for logStreamsPaginator . HasMorePages () {
117+ page , err = logStreamsPaginator . NextPage ( ctx )
118+ if err != nil {
119+ return
131120 }
132- return ! lastPage
133- })
134- return streams , err
121+ streams = append ( streams , page . LogStreams ... )
122+ }
123+ return
135124}
136125
137126// GetEvents gets events from AWS given the blade configuration
138- func (b * Blade ) GetEvents () (err error ) {
127+ func (b * Blade ) GetEvents (ctx context. Context ) (err error ) {
139128 if err := b .ResolveFuzzyGroupName (); err != nil {
140129 return err
141130 }
142131 formatter := b .output .Formatter ()
143132 input := b .config .FilterLogEventsInput ()
144-
145- handlePage := func (page * cloudwatchlogs.FilterLogEventsOutput , lastPage bool ) bool {
133+ logEventsPaginator := cloudwatchlogs .NewFilterLogEventsPaginator (b .cwl , input )
134+ var page * cloudwatchlogs.FilterLogEventsOutput
135+ for logEventsPaginator .HasMorePages () {
136+ page , err = logEventsPaginator .NextPage (ctx )
137+ if err != nil {
138+ return
139+ }
146140 for _ , event := range page .Events {
147141 if b .output .Pretty {
148142 fmt .Println (strings .TrimRight (formatEvent (formatter , event ), "\n " ))
149143 } else {
150144 fmt .Println (strings .TrimRight (* event .Message , "\n " ))
151145 }
152146 }
153- return ! lastPage
154147 }
155- return b . cwl . FilterLogEventsPages ( input , handlePage )
148+ return
156149}
157150
158151// StreamEvents continuously prints log events to the console
159- func (b * Blade ) StreamEvents () (err error ) {
152+ func (b * Blade ) StreamEvents (ctx context. Context ) (err error ) {
160153 var lastSeenTime * int64
161154 var seenEventIDs map [string ]bool
162155 formatter := b .output .Formatter ()
@@ -177,46 +170,45 @@ func (b *Blade) StreamEvents() (err error) {
177170 }
178171 }
179172
180- handlePage := func (page * cloudwatchlogs.FilterLogEventsOutput , lastPage bool ) bool {
181- for _ , event := range page .Events {
182- updateLastSeenTime (event .Timestamp )
183- if _ , seen := seenEventIDs [* event .EventId ]; ! seen {
184- var message string
185- if b .output .Raw {
186- message = * event .Message
187- } else {
188- message = formatEvent (formatter , event )
173+ for {
174+ logEventsPaginator := cloudwatchlogs .NewFilterLogEventsPaginator (b .cwl , input )
175+ var page * cloudwatchlogs.FilterLogEventsOutput
176+ for logEventsPaginator .HasMorePages () {
177+ page , err = logEventsPaginator .NextPage (ctx )
178+ if err != nil {
179+ return
180+ }
181+ for _ , event := range page .Events {
182+ updateLastSeenTime (event .Timestamp )
183+ if _ , seen := seenEventIDs [* event .EventId ]; ! seen {
184+ var message string
185+ if b .output .Raw {
186+ message = * event .Message
187+ } else {
188+ message = formatEvent (formatter , event )
189+ }
190+ message = strings .TrimRight (message , "\n " )
191+ fmt .Println (message )
192+ addSeenEventIDs (event .EventId )
189193 }
190- message = strings .TrimRight (message , "\n " )
191- fmt .Println (message )
192- addSeenEventIDs (event .EventId )
193194 }
194195 }
195- return ! lastPage
196- }
197-
198- for {
199- err = b .cwl .FilterLogEventsPages (input , handlePage )
200- if err != nil {
201- return
202- }
203196 if lastSeenTime != nil {
204- input .SetStartTime ( * lastSeenTime )
197+ input .StartTime = lastSeenTime
205198 }
206199 time .Sleep (1 * time .Second )
207200 }
208201}
209202
210203// formatEvent returns a CloudWatch log event as a formatted string using the provided formatter
211- func formatEvent (formatter * colorjson.Formatter , event * cloudwatchlogs .FilteredLogEvent ) string {
204+ func formatEvent (formatter * colorjson.Formatter , event types .FilteredLogEvent ) string {
212205 red := color .New (color .FgRed ).SprintFunc ()
213206 white := color .New (color .FgWhite ).SprintFunc ()
214207
215- str := aws .StringValue (event .Message )
216- bytes := []byte (str )
217- date := aws .MillisecondsTimeValue (event .Timestamp )
218- dateStr := date .Format (time .RFC3339 )
219- streamStr := aws .StringValue (event .LogStreamName )
208+ str := * event .Message
209+ bytes := []byte (* event .Message )
210+ dateStr := time .UnixMilli (* event .Timestamp ).Format (time .RFC3339 )
211+ streamStr := * event .LogStreamName
220212 jl := map [string ]interface {}{}
221213
222214 if err := json .Unmarshal (bytes , & jl ); err != nil {
0 commit comments