github.com/blend/go-sdk@v1.20220411.3/redis/event.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package redis 9 10 import ( 11 "context" 12 "fmt" 13 "io" 14 "strings" 15 "time" 16 17 "github.com/blend/go-sdk/ansi" 18 "github.com/blend/go-sdk/logger" 19 "github.com/blend/go-sdk/timeutil" 20 ) 21 22 // Logger flags 23 const ( 24 Flag = "redis" 25 ) 26 27 // these are compile time assertions 28 var ( 29 _ logger.Event = (*Event)(nil) 30 _ logger.TextWritable = (*Event)(nil) 31 _ logger.JSONWritable = (*Event)(nil) 32 ) 33 34 // NewEvent creates a new query event. 35 func NewEvent(op string, args []string, elapsed time.Duration, options ...EventOption) Event { 36 qe := Event{ 37 Op: op, 38 Args: args, 39 Elapsed: elapsed, 40 } 41 for _, opt := range options { 42 opt(&qe) 43 } 44 return qe 45 } 46 47 // NewEventListener returns a new listener for events. 48 func NewEventListener(listener func(context.Context, Event)) logger.Listener { 49 return func(ctx context.Context, e logger.Event) { 50 if typed, isTyped := e.(Event); isTyped { 51 listener(ctx, typed) 52 } 53 } 54 } 55 56 // NewEventFilter returns a new event filter. 57 func NewEventFilter(filter func(context.Context, Event) (Event, bool)) logger.Filter { 58 return func(ctx context.Context, e logger.Event) (logger.Event, bool) { 59 if typed, isTyped := e.(Event); isTyped { 60 return filter(ctx, typed) 61 } 62 return e, false 63 } 64 } 65 66 // EventOption mutates an event. 67 type EventOption func(*Event) 68 69 // OptEventNetwork sets a field on the event. 70 func OptEventNetwork(value string) EventOption { 71 return func(e *Event) { e.Network = value } 72 } 73 74 // OptEventAddr sets a field on the event. 75 func OptEventAddr(value string) EventOption { 76 return func(e *Event) { e.Addr = value } 77 } 78 79 // OptEventDB sets a field on the event. 80 func OptEventDB(value string) EventOption { 81 return func(e *Event) { e.DB = value } 82 } 83 84 // OptEventAuthUser sets a field on the event. 85 func OptEventAuthUser(value string) EventOption { 86 return func(e *Event) { e.AuthUser = value } 87 } 88 89 // OptEventOp sets a field on the event. 90 func OptEventOp(value string) EventOption { 91 return func(e *Event) { e.Op = value } 92 } 93 94 // OptEventArgs sets a field on the event. 95 func OptEventArgs(values ...string) EventOption { 96 return func(e *Event) { e.Args = values } 97 } 98 99 // OptEventElapsed sets a field on the event. 100 func OptEventElapsed(value time.Duration) EventOption { 101 return func(e *Event) { e.Elapsed = value } 102 } 103 104 // OptEventErr sets a field on the event. 105 func OptEventErr(value error) EventOption { 106 return func(e *Event) { e.Err = value } 107 } 108 109 // Event represents a call to redis. 110 type Event struct { 111 Network string 112 Addr string 113 AuthUser string 114 DB string 115 Op string 116 Args []string 117 Elapsed time.Duration 118 Err error 119 } 120 121 // GetFlag implements Event. 122 func (e Event) GetFlag() string { return Flag } 123 124 // WriteText writes the event text to the output. 125 func (e Event) WriteText(tf logger.TextFormatter, wr io.Writer) { 126 fmt.Fprint(wr, "[") 127 if len(e.AuthUser) > 0 { 128 fmt.Fprint(wr, tf.Colorize(e.AuthUser, ansi.ColorLightWhite)) 129 fmt.Fprint(wr, "@") 130 } 131 if len(e.Addr) > 0 { 132 fmt.Fprint(wr, tf.Colorize(e.Addr, ansi.ColorLightWhite)) 133 } 134 if e.DB != "" { 135 fmt.Fprint(wr, "/") 136 fmt.Fprint(wr, tf.Colorize(fmt.Sprint(e.DB), ansi.ColorLightWhite)) 137 } 138 fmt.Fprint(wr, "]") 139 140 if len(e.Op) > 0 { 141 fmt.Fprint(wr, logger.Space) 142 fmt.Fprintf(wr, "[%s]", tf.Colorize(e.Op, ansi.ColorLightBlue)) 143 } 144 if len(e.Args) > 0 { 145 fmt.Fprint(wr, logger.Space) 146 fmt.Fprintf(wr, "%s", strings.Join(e.Args, ", ")) 147 } 148 149 fmt.Fprint(wr, logger.Space) 150 fmt.Fprint(wr, e.Elapsed.String()) 151 152 if e.Err != nil { 153 fmt.Fprint(wr, logger.Space) 154 fmt.Fprint(wr, tf.Colorize("failed", ansi.ColorRed)) 155 } 156 } 157 158 // Decompose implements JSONWritable. 159 func (e Event) Decompose() map[string]interface{} { 160 return map[string]interface{}{ 161 "addr": e.Addr, 162 "db": e.DB, 163 "op": e.Op, 164 "args": e.Args, 165 "elapsed": timeutil.Milliseconds(e.Elapsed), 166 "err": e.Err, 167 } 168 }