@@ -17,6 +17,7 @@ import (
17
17
"github.com/bitly/nsq/internal/http_api"
18
18
"github.com/bitly/nsq/internal/protocol"
19
19
"github.com/bitly/nsq/internal/version"
20
+ "github.com/hashicorp/serf/serf"
20
21
)
21
22
22
23
type httpServer struct {
@@ -179,6 +180,10 @@ func (s *httpServer) pingHandler(w http.ResponseWriter, req *http.Request) {
179
180
if ! s .ctx .nsqd .IsHealthy () {
180
181
code = 500
181
182
}
183
+ if s .ctx .nsqd .serf != nil && (s .ctx .nsqd .serf .State () == serf .SerfAlive || len (s .ctx .nsqd .serf .Members ()) < 2 ) {
184
+ code = 500
185
+ health = "NOK - gossip unhealthy"
186
+ }
182
187
w .Header ().Set ("Content-Length" , strconv .Itoa (len (health )))
183
188
w .WriteHeader (code )
184
189
io .WriteString (w , health )
@@ -233,6 +238,10 @@ func (s *httpServer) getTopicFromQuery(req *http.Request) (url.Values, *Topic, e
233
238
}
234
239
235
240
func (s * httpServer ) doLookup (req * http.Request ) (interface {}, error ) {
241
+ if s .ctx .nsqd .serf == nil || s .ctx .nsqd .serf .State () != serf .SerfAlive {
242
+ return nil , http_api.Err {400 , "GOSSIP_NOT_ENABLED" }
243
+ }
244
+
236
245
reqParams , err := http_api .NewReqParams (req )
237
246
if err != nil {
238
247
return nil , http_api.Err {400 , "INVALID_REQUEST" }
@@ -528,8 +537,13 @@ func (s *httpServer) doStats(req *http.Request) (interface{}, error) {
528
537
startTime := s .ctx .nsqd .GetStartTime ()
529
538
uptime := time .Since (startTime )
530
539
540
+ var serfStats map [string ]string
541
+ if s .ctx .nsqd .serf != nil {
542
+ serfStats = s .ctx .nsqd .serf .Stats ()
543
+ }
544
+
531
545
if ! jsonFormat {
532
- return s .printStats (stats , health , startTime , uptime ), nil
546
+ return s .printStats (stats , health , startTime , uptime , serfStats ), nil
533
547
}
534
548
535
549
return struct {
@@ -540,56 +554,55 @@ func (s *httpServer) doStats(req *http.Request) (interface{}, error) {
540
554
}{version .Binary , health , startTime .Unix (), stats }, nil
541
555
}
542
556
543
- func (s * httpServer ) printStats (stats []TopicStats , health string , startTime time.Time , uptime time.Duration ) []byte {
544
- var buf bytes.Buffer
545
- w := & buf
557
+ func (s * httpServer ) printStats (stats []TopicStats , health string , startTime time.Time , uptime time.Duration , gossip map [string ]string ) []byte {
558
+ w := & bytes.Buffer {}
546
559
now := time .Now ()
547
- io . WriteString (w , fmt . Sprintf ( "%s\n " , version .String ("nsqd" ) ))
548
- io . WriteString (w , fmt . Sprintf ( "start_time %v\n " , startTime .Format (time .RFC3339 ) ))
549
- io . WriteString (w , fmt . Sprintf ( "uptime %s\n " , uptime ) )
560
+ fmt . Fprintf (w , "%s\n " , version .String ("nsqd" ))
561
+ fmt . Fprintf (w , "start_time %v\n " , startTime .Format (time .RFC3339 ))
562
+ fmt . Fprintf (w , "uptime %s\n " , uptime )
550
563
if len (stats ) == 0 {
551
- io .WriteString (w , "\n NO_TOPICS\n " )
552
- return buf .Bytes ()
564
+ w .WriteString ("\n NO_TOPICS\n " )
565
+ return w .Bytes ()
553
566
}
554
- io . WriteString (w , fmt . Sprintf ( "\n Health: %s\n " , health ) )
567
+ fmt . Fprintf (w , "\n Health: %s\n " , health )
555
568
for _ , t := range stats {
556
569
var pausedPrefix string
557
570
if t .Paused {
558
571
pausedPrefix = "*P "
559
572
} else {
560
573
pausedPrefix = " "
561
574
}
562
- io . WriteString (w , fmt . Sprintf ( "\n %s[%-15s] depth: %-5d be-depth: %-5d msgs: %-8d e2e%%: %s\n " ,
575
+ fmt . Fprintf (w , "\n %s[%-15s] depth: %-5d be-depth: %-5d msgs: %-8d e2e%%: %s\n " ,
563
576
pausedPrefix ,
564
577
t .TopicName ,
565
578
t .Depth ,
566
579
t .BackendDepth ,
567
580
t .MessageCount ,
568
- t .E2eProcessingLatency ))
581
+ t .E2eProcessingLatency )
569
582
for _ , c := range t .Channels {
570
583
if c .Paused {
571
584
pausedPrefix = " *P "
572
585
} else {
573
586
pausedPrefix = " "
574
587
}
575
- io . WriteString (w ,
576
- fmt . Sprintf ( "%s[%-25s] depth: %-5d be-depth: %-5d inflt: %-4d def: %-4d re-q: %-5d timeout: %-5d msgs: %-8d e2e%%: %s\n " ,
577
- pausedPrefix ,
578
- c .ChannelName ,
579
- c .Depth ,
580
- c .BackendDepth ,
581
- c .InFlightCount ,
582
- c .DeferredCount ,
583
- c .RequeueCount ,
584
- c .TimeoutCount ,
585
- c .MessageCount ,
586
- c .E2eProcessingLatency ) )
588
+ fmt . Fprintf (w ,
589
+ "%s[%-25s] depth: %-5d be-depth: %-5d inflt: %-4d def: %-4d re-q: %-5d timeout: %-5d msgs: %-8d e2e%%: %s\n " ,
590
+ pausedPrefix ,
591
+ c .ChannelName ,
592
+ c .Depth ,
593
+ c .BackendDepth ,
594
+ c .InFlightCount ,
595
+ c .DeferredCount ,
596
+ c .RequeueCount ,
597
+ c .TimeoutCount ,
598
+ c .MessageCount ,
599
+ c .E2eProcessingLatency )
587
600
for _ , client := range c .Clients {
588
601
connectTime := time .Unix (client .ConnectTime , 0 )
589
602
// truncate to the second
590
603
duration := time .Duration (int64 (now .Sub (connectTime ).Seconds ())) * time .Second
591
604
_ , port , _ := net .SplitHostPort (client .RemoteAddress )
592
- io . WriteString (w , fmt . Sprintf ( " [%s %-21s] state: %d inflt: %-4d rdy: %-4d fin: %-8d re-q: %-8d msgs: %-8d connected: %s\n " ,
605
+ fmt . Fprintf (w , " [%s %-21s] state: %d inflt: %-4d rdy: %-4d fin: %-8d re-q: %-8d msgs: %-8d connected: %s\n " ,
593
606
client .Version ,
594
607
fmt .Sprintf ("%s:%s" , client .Name , port ),
595
608
client .State ,
@@ -599,9 +612,17 @@ func (s *httpServer) printStats(stats []TopicStats, health string, startTime tim
599
612
client .RequeueCount ,
600
613
client .MessageCount ,
601
614
duration ,
602
- ))
615
+ )
603
616
}
604
617
}
605
618
}
606
- return buf .Bytes ()
619
+
620
+ if gossip != nil {
621
+ fmt .Fprintf (w , "\n Gossip:\n " )
622
+ for k , v := range gossip {
623
+ fmt .Fprintf (w , " %s: %s\n " , k , v )
624
+ }
625
+ }
626
+
627
+ return w .Bytes ()
607
628
}
0 commit comments