github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/debug/handler/handler.go (about) 1 // Package handler implements service debug handler embedded in go-micro services 2 package handler 3 4 import ( 5 "context" 6 "time" 7 8 pb "github.com/tickoalcantara12/micro/v3/proto/debug" 9 "github.com/tickoalcantara12/micro/v3/service/debug" 10 "github.com/tickoalcantara12/micro/v3/service/debug/log" 11 "github.com/tickoalcantara12/micro/v3/service/debug/stats" 12 "github.com/tickoalcantara12/micro/v3/service/debug/trace" 13 ) 14 15 // NewHandler returns an instance of the Debug Handler 16 func NewHandler() *Debug { 17 return &Debug{ 18 log: debug.DefaultLog, 19 stats: debug.DefaultStats, 20 trace: debug.DefaultTracer, 21 } 22 } 23 24 type Debug struct { 25 // must honour the debug handler 26 pb.DebugHandler 27 // the logger for retrieving logs 28 log log.Log 29 // the stats collector 30 stats stats.Stats 31 // the tracer 32 trace trace.Tracer 33 } 34 35 func (d *Debug) Health(ctx context.Context, req *pb.HealthRequest, rsp *pb.HealthResponse) error { 36 rsp.Status = "ok" 37 return nil 38 } 39 40 func (d *Debug) Stats(ctx context.Context, req *pb.StatsRequest, rsp *pb.StatsResponse) error { 41 stats, err := d.stats.Read() 42 if err != nil { 43 return err 44 } 45 46 if len(stats) == 0 { 47 return nil 48 } 49 50 // write the response values 51 rsp.Timestamp = uint64(stats[0].Timestamp) 52 rsp.Started = uint64(stats[0].Started) 53 rsp.Uptime = uint64(stats[0].Uptime) 54 rsp.Memory = stats[0].Memory 55 rsp.Gc = stats[0].GC 56 rsp.Threads = stats[0].Threads 57 rsp.Requests = stats[0].Requests 58 rsp.Errors = stats[0].Errors 59 60 return nil 61 } 62 63 func (d *Debug) Trace(ctx context.Context, req *pb.TraceRequest, rsp *pb.TraceResponse) error { 64 traces, err := d.trace.Read(trace.ReadTrace(req.Id)) 65 if err != nil { 66 return err 67 } 68 69 for _, t := range traces { 70 var typ pb.SpanType 71 switch t.Type { 72 case trace.SpanTypeRequestInbound: 73 typ = pb.SpanType_INBOUND 74 case trace.SpanTypeRequestOutbound: 75 typ = pb.SpanType_OUTBOUND 76 } 77 rsp.Spans = append(rsp.Spans, &pb.Span{ 78 Trace: t.Trace, 79 Id: t.Id, 80 Parent: t.Parent, 81 Name: t.Name, 82 Started: uint64(t.Started.UnixNano()), 83 Duration: uint64(t.Duration.Nanoseconds()), 84 Type: typ, 85 Metadata: t.Metadata, 86 }) 87 } 88 89 return nil 90 } 91 92 // Log returns some log lines 93 func (d *Debug) Log(ctx context.Context, req pb.LogRequest, rsp *pb.LogResponse) error { 94 var options []log.ReadOption 95 96 since := time.Unix(req.Since, 0) 97 if !since.IsZero() { 98 options = append(options, log.Since(since)) 99 } 100 101 count := int(req.Count) 102 if count > 0 { 103 options = append(options, log.Count(count)) 104 } 105 106 // get the log records 107 records, err := d.log.Read(options...) 108 if err != nil { 109 return err 110 } 111 112 for _, record := range records { 113 // copy metadata 114 metadata := make(map[string]string) 115 for k, v := range record.Metadata { 116 metadata[k] = v 117 } 118 // send record 119 rsp.Records = append(rsp.Records, &pb.Record{ 120 Timestamp: record.Timestamp.Unix(), 121 Message: record.Message.(string), 122 Metadata: metadata, 123 }) 124 } 125 126 return nil 127 }