Move stream to interface
This commit is contained in:
@@ -71,10 +71,13 @@ func (d *Debug) Log(ctx context.Context, stream server.Stream) error {
|
||||
// the connection stays open until some timeout expires
|
||||
// or something like that; that means the map of streams
|
||||
// might end up leaking memory if not cleaned up properly
|
||||
records, stop := d.log.Stream()
|
||||
defer close(stop)
|
||||
lgStream, err := d.log.Stream()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lgStream.Stop()
|
||||
|
||||
for record := range records {
|
||||
for record := range lgStream.Chan() {
|
||||
if err := d.sendRecord(record, stream); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -85,7 +88,10 @@ func (d *Debug) Log(ctx context.Context, stream server.Stream) error {
|
||||
}
|
||||
|
||||
// get the log records
|
||||
records := d.log.Read(options...)
|
||||
records, err := d.log.Read(options...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// send all the logs downstream
|
||||
for _, record := range records {
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/debug"
|
||||
"github.com/micro/go-micro/debug/log"
|
||||
)
|
||||
@@ -10,50 +12,36 @@ type serviceLog struct {
|
||||
}
|
||||
|
||||
// Read reads log entries from the logger
|
||||
func (s *serviceLog) Read(opts ...log.ReadOption) []log.Record {
|
||||
// TODO: parse opts
|
||||
stream, err := s.Client.Log(opts...)
|
||||
if err != nil {
|
||||
return nil
|
||||
func (s *serviceLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
|
||||
var options log.ReadOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
stream, err := s.Client.Log(options.Since, options.Count, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer stream.Stop()
|
||||
|
||||
// stream the records until nothing is left
|
||||
var records []log.Record
|
||||
for record := range stream {
|
||||
|
||||
for record := range stream.Chan() {
|
||||
records = append(records, record)
|
||||
}
|
||||
return records
|
||||
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// There is no write support
|
||||
func (s *serviceLog) Write(r log.Record) {
|
||||
return
|
||||
func (s *serviceLog) Write(r log.Record) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stream log records
|
||||
func (s *serviceLog) Stream() (<-chan log.Record, chan bool) {
|
||||
stop := make(chan bool)
|
||||
stream, err := s.Client.Log(log.Stream(true))
|
||||
if err != nil {
|
||||
// return a closed stream
|
||||
deadStream := make(chan log.Record)
|
||||
close(deadStream)
|
||||
return deadStream, stop
|
||||
}
|
||||
|
||||
newStream := make(chan log.Record, 128)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case rec := <-stream:
|
||||
newStream <- rec
|
||||
case <-stop:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return newStream, stop
|
||||
func (s *serviceLog) Stream() (log.Stream, error) {
|
||||
return s.Client.Log(time.Time{}, 0, true)
|
||||
}
|
||||
|
||||
// NewLog returns a new log interface
|
||||
|
@@ -27,42 +27,40 @@ func NewClient(name string) *debugClient {
|
||||
}
|
||||
}
|
||||
|
||||
// Logs queries the service logs and returns a channel to read the logs from
|
||||
func (d *debugClient) Log(opts ...log.ReadOption) (<-chan log.Record, error) {
|
||||
var options log.ReadOptions
|
||||
// initialize the read options
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
// Logs queries the services logs and returns a channel to read the logs from
|
||||
func (d *debugClient) Log(since time.Time, count int, stream bool) (log.Stream, error) {
|
||||
req := &pb.LogRequest{}
|
||||
if !options.Since.IsZero() {
|
||||
req.Since = options.Since.Unix()
|
||||
if !since.IsZero() {
|
||||
req.Since = since.Unix()
|
||||
}
|
||||
|
||||
if options.Count > 0 {
|
||||
req.Count = int64(options.Count)
|
||||
if count > 0 {
|
||||
req.Count = int64(count)
|
||||
}
|
||||
|
||||
req.Stream = options.Stream
|
||||
// set whether to stream
|
||||
req.Stream = stream
|
||||
|
||||
// get the log stream
|
||||
stream, err := d.Client.Log(context.Background(), req)
|
||||
serverStream, err := d.Client.Log(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed getting log stream: %s", err)
|
||||
}
|
||||
|
||||
// log channel for streaming logs
|
||||
logChan := make(chan log.Record)
|
||||
lg := &logStream{
|
||||
stream: make(chan log.Record),
|
||||
stop: make(chan bool),
|
||||
}
|
||||
|
||||
// go stream logs
|
||||
go d.streamLogs(logChan, stream)
|
||||
go d.streamLogs(lg, serverStream)
|
||||
|
||||
return logChan, nil
|
||||
return lg, nil
|
||||
}
|
||||
|
||||
func (d *debugClient) streamLogs(logChan chan log.Record, stream pb.Debug_LogService) {
|
||||
func (d *debugClient) streamLogs(lg *logStream, stream pb.Debug_LogService) {
|
||||
defer stream.Close()
|
||||
defer lg.Stop()
|
||||
|
||||
for {
|
||||
resp, err := stream.Recv()
|
||||
@@ -81,8 +79,10 @@ func (d *debugClient) streamLogs(logChan chan log.Record, stream pb.Debug_LogSer
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
logChan <- record
|
||||
select {
|
||||
case <-lg.stop:
|
||||
return
|
||||
case lg.stream <- record:
|
||||
}
|
||||
}
|
||||
|
||||
close(logChan)
|
||||
}
|
||||
|
25
debug/service/stream.go
Normal file
25
debug/service/stream.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/debug/log"
|
||||
)
|
||||
|
||||
type logStream struct {
|
||||
stream chan log.Record
|
||||
stop chan bool
|
||||
}
|
||||
|
||||
func (l *logStream) Chan() <-chan log.Record {
|
||||
return l.stream
|
||||
}
|
||||
|
||||
func (l *logStream) Stop() error {
|
||||
select {
|
||||
case <-l.stop:
|
||||
return nil
|
||||
default:
|
||||
close(l.stream)
|
||||
close(l.stop)
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user