github.com/blend/go-sdk@v1.20220411.3/grpcutil/rpc_stream_message_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 grpcutil 9 10 import ( 11 "context" 12 "fmt" 13 "io" 14 "time" 15 16 "github.com/blend/go-sdk/ansi" 17 "github.com/blend/go-sdk/logger" 18 "github.com/blend/go-sdk/timeutil" 19 ) 20 21 // Logger flags 22 const ( 23 FlagRPCStreamMessage = "rpc.stream.message" 24 ) 25 26 // these are compile time assertions 27 var ( 28 _ logger.Event = (*RPCStreamMessageEvent)(nil) 29 _ logger.TextWritable = (*RPCStreamMessageEvent)(nil) 30 _ logger.JSONWritable = (*RPCStreamMessageEvent)(nil) 31 ) 32 33 // StreamMessageDirection is the direction the message was sent. 34 type StreamMessageDirection string 35 36 // constants 37 const ( 38 StreamMessageDirectionReceive = "recv" 39 StreamMessageDirectionSend = "send" 40 ) 41 42 // NewRPCStreamMessageEvent creates a new rpc stream message event. 43 func NewRPCStreamMessageEvent(method string, direction StreamMessageDirection, elapsed time.Duration, options ...RPCStreamMessageEventOption) RPCStreamMessageEvent { 44 rpe := RPCStreamMessageEvent{ 45 RPCEvent: RPCEvent{ 46 Engine: EngineGRPC, 47 Method: method, 48 Elapsed: elapsed, 49 }, 50 Direction: direction, 51 } 52 for _, opt := range options { 53 opt(&rpe) 54 } 55 return rpe 56 } 57 58 // NewRPCStreamMessageEventListener returns a new rpc stream message event event listener. 59 func NewRPCStreamMessageEventListener(listener func(context.Context, RPCStreamMessageEvent)) logger.Listener { 60 return func(ctx context.Context, e logger.Event) { 61 if typed, isTyped := e.(RPCStreamMessageEvent); isTyped { 62 listener(ctx, typed) 63 } 64 } 65 } 66 67 // NewRPCStreamMessageEventFilter returns a new rpc stream message event filter. 68 func NewRPCStreamMessageEventFilter(filter func(context.Context, RPCStreamMessageEvent) (RPCStreamMessageEvent, bool)) logger.Filter { 69 return func(ctx context.Context, e logger.Event) (logger.Event, bool) { 70 if typed, isTyped := e.(RPCStreamMessageEvent); isTyped { 71 return filter(ctx, typed) 72 } 73 return e, false 74 } 75 } 76 77 // RPCStreamMessageEventOption is a mutator for RPCEvents. 78 type RPCStreamMessageEventOption func(*RPCStreamMessageEvent) 79 80 // OptRPCStreamMessageEngine sets a field on the event. 81 func OptRPCStreamMessageEngine(value string) RPCStreamMessageEventOption { 82 return func(e *RPCStreamMessageEvent) { e.Engine = value } 83 } 84 85 // OptRPCStreamMessagePeer sets a field on the event. 86 func OptRPCStreamMessagePeer(value string) RPCStreamMessageEventOption { 87 return func(e *RPCStreamMessageEvent) { e.Peer = value } 88 } 89 90 // OptRPCStreamMessageMethod sets a field on the event. 91 func OptRPCStreamMessageMethod(value string) RPCStreamMessageEventOption { 92 return func(e *RPCStreamMessageEvent) { e.Method = value } 93 } 94 95 // OptRPCStreamMessageDirection sets a field on the event. 96 func OptRPCStreamMessageDirection(value StreamMessageDirection) RPCStreamMessageEventOption { 97 return func(e *RPCStreamMessageEvent) { e.Direction = value } 98 } 99 100 // OptRPCStreamMessageUserAgent sets a field on the event. 101 func OptRPCStreamMessageUserAgent(value string) RPCStreamMessageEventOption { 102 return func(e *RPCStreamMessageEvent) { e.UserAgent = value } 103 } 104 105 // OptRPCStreamMessageAuthority sets a field on the event. 106 func OptRPCStreamMessageAuthority(value string) RPCStreamMessageEventOption { 107 return func(e *RPCStreamMessageEvent) { e.Authority = value } 108 } 109 110 // OptRPCStreamMessageContentType sets a field on the event. 111 func OptRPCStreamMessageContentType(value string) RPCStreamMessageEventOption { 112 return func(e *RPCStreamMessageEvent) { e.ContentType = value } 113 } 114 115 // OptRPCStreamMessageElapsed sets a field on the event. 116 func OptRPCStreamMessageElapsed(value time.Duration) RPCStreamMessageEventOption { 117 return func(e *RPCStreamMessageEvent) { e.Elapsed = value } 118 } 119 120 // OptRPCStreamMessageErr sets a field on the event. 121 func OptRPCStreamMessageErr(value error) RPCStreamMessageEventOption { 122 return func(e *RPCStreamMessageEvent) { e.Err = value } 123 } 124 125 // RPCStreamMessageEvent is an event type for rpc 126 type RPCStreamMessageEvent struct { 127 RPCEvent 128 Direction StreamMessageDirection 129 } 130 131 // GetFlag implements Event. 132 func (e RPCStreamMessageEvent) GetFlag() string { return FlagRPCStreamMessage } 133 134 // WriteText implements TextWritable. 135 func (e RPCStreamMessageEvent) WriteText(tf logger.TextFormatter, wr io.Writer) { 136 if e.Engine != "" { 137 fmt.Fprint(wr, "[") 138 fmt.Fprint(wr, tf.Colorize(e.Engine, ansi.ColorLightWhite)) 139 fmt.Fprint(wr, "]") 140 } 141 if e.Method != "" { 142 if e.Engine != "" { 143 fmt.Fprint(wr, logger.Space) 144 } 145 fmt.Fprint(wr, tf.Colorize(e.Method, ansi.ColorBlue)) 146 } 147 if e.Direction != "" { 148 fmt.Fprint(wr, logger.Space) 149 fmt.Fprint(wr, e.Direction) 150 } 151 if e.Peer != "" { 152 fmt.Fprint(wr, logger.Space) 153 fmt.Fprint(wr, e.Peer) 154 } 155 if e.Authority != "" { 156 fmt.Fprint(wr, logger.Space) 157 fmt.Fprint(wr, e.Authority) 158 } 159 if e.UserAgent != "" { 160 fmt.Fprint(wr, logger.Space) 161 fmt.Fprint(wr, e.UserAgent) 162 } 163 if e.ContentType != "" { 164 fmt.Fprint(wr, logger.Space) 165 fmt.Fprint(wr, e.ContentType) 166 } 167 168 fmt.Fprint(wr, logger.Space) 169 fmt.Fprint(wr, e.Elapsed.String()) 170 171 if e.Err != nil { 172 fmt.Fprint(wr, logger.Space) 173 fmt.Fprint(wr, tf.Colorize("failed", ansi.ColorRed)) 174 } 175 } 176 177 // Decompose implements JSONWritable. 178 func (e RPCStreamMessageEvent) Decompose() map[string]interface{} { 179 return map[string]interface{}{ 180 "engine": e.Engine, 181 "peer": e.Peer, 182 "method": e.Method, 183 "direction": e.Direction, 184 "userAgent": e.UserAgent, 185 "authority": e.Authority, 186 "contentType": e.ContentType, 187 "elapsed": timeutil.Milliseconds(e.Elapsed), 188 "err": e.Err, 189 } 190 }