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  }