Skip to content

Commit dc4b9e4

Browse files
committed
Improve with logging deep components
Propogate context with logger to ToxicCollection, ToxicLink.
1 parent 77dfc2f commit dc4b9e4

File tree

7 files changed

+131
-71
lines changed

7 files changed

+131
-71
lines changed

api.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ import (
1616
"github.com/Shopify/toxiproxy/v2/toxics"
1717
)
1818

19+
func stopBrowsersMiddleware(next http.Handler) http.Handler {
20+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21+
if strings.HasPrefix(r.UserAgent(), "Mozilla/") {
22+
http.Error(w, "User agent not allowed", 403)
23+
} else {
24+
next.ServeHTTP(w, r)
25+
}
26+
})
27+
}
28+
29+
func timeoutMiddleware(next http.Handler) http.Handler {
30+
return http.TimeoutHandler(next, 30*time.Second, "")
31+
}
32+
1933
type ApiServer struct {
2034
Collection *ProxyCollection
2135
Metrics *metricsContainer
@@ -46,20 +60,6 @@ func (server *ApiServer) PopulateConfig(filename string) {
4660
}
4761
}
4862

49-
func stopBrowsersMiddleware(next http.Handler) http.Handler {
50-
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
51-
if strings.HasPrefix(r.UserAgent(), "Mozilla/") {
52-
http.Error(w, "User agent not allowed", 403)
53-
} else {
54-
next.ServeHTTP(w, r)
55-
}
56-
})
57-
}
58-
59-
func timeoutMiddleware(next http.Handler) http.Handler {
60-
return http.TimeoutHandler(next, 5*time.Second, "")
61-
}
62-
6363
func (server *ApiServer) Listen(host string, port string) {
6464
r := mux.NewRouter()
6565
r.Use(hlog.NewHandler(*server.Logger))
@@ -153,6 +153,7 @@ func (server *ApiServer) ProxyIndex(response http.ResponseWriter, request *http.
153153
}
154154

155155
func (server *ApiServer) ResetState(response http.ResponseWriter, request *http.Request) {
156+
ctx := request.Context()
156157
proxies := server.Collection.Proxies()
157158

158159
for _, proxy := range proxies {
@@ -161,13 +162,13 @@ func (server *ApiServer) ResetState(response http.ResponseWriter, request *http.
161162
return
162163
}
163164

164-
proxy.Toxics.ResetToxics()
165+
proxy.Toxics.ResetToxics(ctx)
165166
}
166167

167168
response.WriteHeader(http.StatusNoContent)
168169
_, err := response.Write(nil)
169170
if err != nil {
170-
log := zerolog.Ctx(request.Context())
171+
log := zerolog.Ctx(ctx)
171172
log.Warn().Err(err).Msg("ResetState: Failed to write headers to client")
172173
}
173174
}
@@ -414,21 +415,22 @@ func (server *ApiServer) ToxicUpdate(response http.ResponseWriter, request *http
414415

415416
func (server *ApiServer) ToxicDelete(response http.ResponseWriter, request *http.Request) {
416417
vars := mux.Vars(request)
418+
ctx := request.Context()
419+
log := zerolog.Ctx(ctx)
417420

418421
proxy, err := server.Collection.Get(vars["proxy"])
419422
if server.apiError(response, err) {
420423
return
421424
}
422425

423-
err = proxy.Toxics.RemoveToxic(vars["toxic"])
426+
err = proxy.Toxics.RemoveToxic(ctx, vars["toxic"])
424427
if server.apiError(response, err) {
425428
return
426429
}
427430

428431
response.WriteHeader(http.StatusNoContent)
429432
_, err = response.Write(nil)
430433
if err != nil {
431-
log := zerolog.Ctx(request.Context())
432434
log.Warn().Err(err).Msg("ToxicDelete: Failed to write headers to client")
433435
}
434436
}

link.go

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package toxiproxy
22

33
import (
4+
"context"
5+
"fmt"
46
"io"
57
"net"
68

@@ -183,23 +185,36 @@ func (link *ToxicLink) UpdateToxic(toxic *toxics.ToxicWrapper) {
183185
}
184186

185187
// Remove an existing toxic from the chain.
186-
func (link *ToxicLink) RemoveToxic(toxic *toxics.ToxicWrapper) {
187-
i := toxic.Index
188+
func (link *ToxicLink) RemoveToxic(ctx context.Context, toxic *toxics.ToxicWrapper) {
189+
toxic_index := toxic.Index
190+
log := zerolog.Ctx(ctx).
191+
With().
192+
Str("component", "ToxicLink").
193+
Str("method", "RemoveToxic").
194+
Str("toxic", toxic.Name).
195+
Str("toxic_type", toxic.Type).
196+
Int("toxic_index", toxic.Index).
197+
Str("link_addr", fmt.Sprintf("%p", link)).
198+
Str("toxic_stub_addr", fmt.Sprintf("%p", link.stubs[toxic_index])).
199+
Str("prev_toxic_stub_addr", fmt.Sprintf("%p", link.stubs[toxic_index-1])).
200+
Logger()
188201

189-
if link.stubs[i].InterruptToxic() {
202+
if link.stubs[toxic_index].InterruptToxic() {
190203
cleanup, ok := toxic.Toxic.(toxics.CleanupToxic)
191204
if ok {
192-
cleanup.Cleanup(link.stubs[i])
205+
cleanup.Cleanup(link.stubs[toxic_index])
193206
// Cleanup could have closed the stub.
194-
if link.stubs[i].Closed() {
207+
if link.stubs[toxic_index].Closed() {
208+
log.Trace().Msg("Cleanup closed toxic and removed toxic")
209+
// TODO: Check if cleanup happen would link.stubs recalculated?
195210
return
196211
}
197212
}
198213

214+
log.Trace().Msg("Interrupt the previous toxic to update its output")
199215
stop := make(chan bool)
200-
// Interrupt the previous toxic to update its output
201216
go func() {
202-
stop <- link.stubs[i-1].InterruptToxic()
217+
stop <- link.stubs[toxic_index-1].InterruptToxic()
203218
}()
204219

205220
// Unblock the previous toxic if it is trying to flush
@@ -210,32 +225,32 @@ func (link *ToxicLink) RemoveToxic(toxic *toxics.ToxicWrapper) {
210225
select {
211226
case interrupted = <-stop:
212227
stopped = true
213-
case tmp := <-link.stubs[i].Input:
228+
case tmp := <-link.stubs[toxic_index].Input:
214229
if tmp == nil {
215-
link.stubs[i].Close()
230+
link.stubs[toxic_index].Close()
216231
if !stopped {
217232
<-stop
218233
}
219234
return
220235
}
221-
link.stubs[i].Output <- tmp
236+
link.stubs[toxic_index].Output <- tmp
222237
}
223238
}
224239

225240
// Empty the toxic's buffer if necessary
226-
for len(link.stubs[i].Input) > 0 {
227-
tmp := <-link.stubs[i].Input
241+
for len(link.stubs[toxic_index].Input) > 0 {
242+
tmp := <-link.stubs[toxic_index].Input
228243
if tmp == nil {
229-
link.stubs[i].Close()
244+
link.stubs[toxic_index].Close()
230245
return
231246
}
232-
link.stubs[i].Output <- tmp
247+
link.stubs[toxic_index].Output <- tmp
233248
}
234249

235-
link.stubs[i-1].Output = link.stubs[i].Output
236-
link.stubs = append(link.stubs[:i], link.stubs[i+1:]...)
250+
link.stubs[toxic_index-1].Output = link.stubs[toxic_index].Output
251+
link.stubs = append(link.stubs[:toxic_index], link.stubs[toxic_index+1:]...)
237252

238-
go link.stubs[i-1].Run(link.toxics.chain[link.direction][i-1])
253+
go link.stubs[toxic_index-1].Run(link.toxics.chain[link.direction][toxic_index-1])
239254
}
240255
}
241256

link_test.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package toxiproxy
22

33
import (
4+
"context"
45
"encoding/binary"
6+
"flag"
57
"io"
8+
"os"
69
"testing"
710
"time"
811

@@ -81,6 +84,7 @@ func TestStubInitializaationWithToxics(t *testing.T) {
8184
}
8285

8386
func TestAddRemoveStubs(t *testing.T) {
87+
ctx := context.Background()
8488
collection := NewToxicCollection(nil)
8589
link := NewToxicLink(nil, collection, stream.Downstream, zerolog.Nop())
8690
go link.stubs[0].Run(collection.chain[stream.Downstream][0])
@@ -117,7 +121,7 @@ func TestAddRemoveStubs(t *testing.T) {
117121
}
118122

119123
// Remove stubs
120-
collection.chainRemoveToxic(toxic)
124+
collection.chainRemoveToxic(ctx, toxic)
121125
if cap(link.stubs[len(link.stubs)-1].Output) != 0 {
122126
t.Fatalf("Link output buffer was not initialized as 0: %d", cap(link.stubs[0].Output))
123127
}
@@ -134,6 +138,7 @@ func TestAddRemoveStubs(t *testing.T) {
134138
}
135139

136140
func TestNoDataDropped(t *testing.T) {
141+
ctx := context.Background()
137142
collection := NewToxicCollection(nil)
138143
link := NewToxicLink(nil, collection, stream.Downstream, zerolog.Nop())
139144
go link.stubs[0].Run(collection.chain[stream.Downstream][0])
@@ -159,17 +164,17 @@ func TestNoDataDropped(t *testing.T) {
159164
}
160165
link.input.Close()
161166
}()
162-
go func() {
167+
go func(ctx context.Context) {
163168
for {
164169
select {
165170
case <-done:
166171
return
167172
default:
168173
collection.chainAddToxic(toxic)
169-
collection.chainRemoveToxic(toxic)
174+
collection.chainRemoveToxic(ctx, toxic)
170175
}
171176
}
172-
}()
177+
}(ctx)
173178

174179
buf := make([]byte, 2)
175180
for i := 0; i < 64*1024; i++ {
@@ -238,7 +243,11 @@ func TestToxicity(t *testing.T) {
238243

239244
func TestStateCreated(t *testing.T) {
240245
collection := NewToxicCollection(nil)
241-
link := NewToxicLink(nil, collection, stream.Downstream, zerolog.Nop())
246+
log := zerolog.Nop()
247+
if flag.Lookup("test.v").DefValue == "true" {
248+
log = zerolog.New(os.Stdout).With().Caller().Timestamp().Logger()
249+
}
250+
link := NewToxicLink(nil, collection, stream.Downstream, log)
242251
go link.stubs[0].Run(collection.chain[stream.Downstream][0])
243252
collection.links["test"] = link
244253

toxic_collection.go

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package toxiproxy
22

33
import (
44
"bytes"
5+
"context"
56
"encoding/json"
67
"fmt"
78
"io"
@@ -43,14 +44,14 @@ func NewToxicCollection(proxy *Proxy) *ToxicCollection {
4344
return collection
4445
}
4546

46-
func (c *ToxicCollection) ResetToxics() {
47+
func (c *ToxicCollection) ResetToxics(ctx context.Context) {
4748
c.Lock()
4849
defer c.Unlock()
4950

5051
// Remove all but the first noop toxic
5152
for dir := range c.chain {
5253
for len(c.chain[dir]) > 1 {
53-
c.chainRemoveToxic(c.chain[dir][1])
54+
c.chainRemoveToxic(ctx, c.chain[dir][1])
5455
}
5556
}
5657
}
@@ -158,16 +159,28 @@ func (c *ToxicCollection) UpdateToxicJson(
158159
return nil, ErrToxicNotFound
159160
}
160161

161-
func (c *ToxicCollection) RemoveToxic(name string) error {
162+
func (c *ToxicCollection) RemoveToxic(ctx context.Context, name string) error {
163+
log := zerolog.Ctx(ctx).
164+
With().
165+
Str("component", "ToxicCollection").
166+
Str("method", "RemoveToxic").
167+
Str("toxic", name).
168+
Str("proxy", c.proxy.Name).
169+
Logger()
170+
log.Trace().Msg("Acquire locking...")
162171
c.Lock()
163172
defer c.Unlock()
164173

174+
log.Trace().Msg("Getting toxic by name...")
165175
toxic := c.findToxicByName(name)
166-
if toxic != nil {
167-
c.chainRemoveToxic(toxic)
168-
return nil
176+
if toxic == nil {
177+
log.Trace().Msg("Could not find toxic by name")
178+
return ErrToxicNotFound
169179
}
170-
return ErrToxicNotFound
180+
181+
c.chainRemoveToxic(ctx, toxic)
182+
log.Trace().Msg("Finished")
183+
return nil
171184
}
172185

173186
func (c *ToxicCollection) StartLink(
@@ -217,17 +230,17 @@ func (c *ToxicCollection) chainAddToxic(toxic *toxics.ToxicWrapper) {
217230
c.chain[dir] = append(c.chain[dir], toxic)
218231

219232
// Asynchronously add the toxic to each link
220-
group := sync.WaitGroup{}
233+
wg := sync.WaitGroup{}
221234
for _, link := range c.links {
222235
if link.direction == dir {
223-
group.Add(1)
224-
go func(link *ToxicLink) {
225-
defer group.Done()
236+
wg.Add(1)
237+
go func(link *ToxicLink, wg *sync.WaitGroup) {
238+
defer wg.Done()
226239
link.AddToxic(toxic)
227-
}(link)
240+
}(link, &wg)
228241
}
229242
}
230-
group.Wait()
243+
wg.Wait()
231244
}
232245

233246
func (c *ToxicCollection) chainUpdateToxic(toxic *toxics.ToxicWrapper) {
@@ -247,25 +260,40 @@ func (c *ToxicCollection) chainUpdateToxic(toxic *toxics.ToxicWrapper) {
247260
group.Wait()
248261
}
249262

250-
func (c *ToxicCollection) chainRemoveToxic(toxic *toxics.ToxicWrapper) {
263+
func (c *ToxicCollection) chainRemoveToxic(ctx context.Context, toxic *toxics.ToxicWrapper) {
264+
log := zerolog.Ctx(ctx).
265+
With().
266+
Str("component", "ToxicCollection").
267+
Str("method", "chainRemoveToxic").
268+
Str("toxic", toxic.Name).
269+
Str("direction", toxic.Direction.String()).
270+
Logger()
271+
251272
dir := toxic.Direction
252273
c.chain[dir] = append(c.chain[dir][:toxic.Index], c.chain[dir][toxic.Index+1:]...)
253274
for i := toxic.Index; i < len(c.chain[dir]); i++ {
254275
c.chain[dir][i].Index = i
255276
}
256277

257278
// Asynchronously remove the toxic from each link
258-
group := sync.WaitGroup{}
279+
wg := sync.WaitGroup{}
280+
281+
event_array := zerolog.Arr()
259282
for _, link := range c.links {
260283
if link.direction == dir {
261-
group.Add(1)
262-
go func(link *ToxicLink) {
263-
defer group.Done()
264-
link.RemoveToxic(toxic)
265-
}(link)
284+
event_array = event_array.Str(fmt.Sprintf("Link[%p] %s", link, link.Direction()))
285+
wg.Add(1)
286+
go func(ctx context.Context, link *ToxicLink, log zerolog.Logger) {
287+
defer wg.Done()
288+
link.RemoveToxic(ctx, toxic)
289+
}(ctx, link, log)
266290
}
267291
}
268-
group.Wait()
292+
293+
log.Trace().
294+
Array("links", event_array).
295+
Msg("Waiting to update links")
296+
wg.Wait()
269297

270298
toxic.Index = -1
271299
}

0 commit comments

Comments
 (0)