Runtime logs (#1447)

* Runtime logs

* Slightly broken

* Pushing for diff

* Log trailing works locally

* LogsOptions

* Comments and streamcount support for local logs

* Adding kubernetes logs

* Fixing k8s logs

* K8s fixes

* StreamCount is now nuked

* PR comments

* PR comments again

* Fix typo
This commit is contained in:
Janos Dobronszki
2020-04-01 15:40:15 +02:00
committed by GitHub
parent 20c95d94cd
commit bb51b8203e
11 changed files with 744 additions and 299 deletions

View File

@@ -2,9 +2,16 @@ package runtime
import (
"errors"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/hpcloud/tail"
"github.com/micro/go-micro/v2/logger"
)
@@ -169,6 +176,11 @@ func (r *runtime) run(events <-chan Event) {
}
}
func logFile(serviceName string) string {
name := strings.Replace(serviceName, "/", "-", -1)
return filepath.Join(os.TempDir(), fmt.Sprintf("%v.log", name))
}
// Create creates a new service which is then started by runtime
func (r *runtime) Create(s *Service, opts ...CreateOption) error {
r.Lock()
@@ -191,6 +203,17 @@ func (r *runtime) Create(s *Service, opts ...CreateOption) error {
// create new service
service := newService(s, options)
f, err := os.OpenFile(logFile(service.Name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
logger.Info(f, err)
if err != nil {
log.Fatal(err)
}
if service.output != nil {
service.output = io.MultiWriter(service.output, f)
} else {
service.output = f
}
// start the service
if err := service.Start(); err != nil {
return err
@@ -202,6 +225,62 @@ func (r *runtime) Create(s *Service, opts ...CreateOption) error {
return nil
}
// @todo: Getting existing lines is not supported yet.
// The reason for this is because it's hard to calculate line offset
// as opposed to character offset.
// This logger streams by default and only supports the `StreamCount` option.
func (r *runtime) Logs(s *Service, options ...LogsOption) (LogStream, error) {
lopts := LogsOptions{}
for _, o := range options {
o(&lopts)
}
ret := &logStream{
service: s.Name,
stream: make(chan LogRecord),
stop: make(chan bool),
}
t, err := tail.TailFile(logFile(s.Name), tail.Config{Follow: true, Location: &tail.SeekInfo{
Whence: 2,
Offset: 0,
}, Logger: tail.DiscardingLogger})
if err != nil {
return nil, err
}
ret.tail = t
go func() {
for line := range t.Lines {
ret.stream <- LogRecord{Message: line.Text}
}
}()
return ret, nil
}
type logStream struct {
tail *tail.Tail
service string
stream chan LogRecord
stop chan bool
}
func (l *logStream) Chan() chan LogRecord {
return l.stream
}
func (l *logStream) Stop() error {
// @todo seems like this is causing a hangup
//err := l.tail.Stop()
//if err != nil {
// return err
//}
select {
case <-l.stop:
return nil
default:
close(l.stop)
}
return nil
}
// Read returns all instances of requested service
// If no service name is provided we return all the track services.
func (r *runtime) Read(opts ...ReadOption) ([]*Service, error) {

View File

@@ -301,6 +301,53 @@ func (k *kubernetes) Init(opts ...runtime.Option) error {
return nil
}
func (k *kubernetes) Logs(s *runtime.Service, options ...runtime.LogsOption) (runtime.LogStream, error) {
klo := newLog(k.client, s.Name, options...)
stream, err := klo.Stream()
if err != nil {
return nil, err
}
// If requested, also read existing records and stream those too
if klo.options.Count > 0 {
go func() {
records, err := klo.Read()
if err != nil {
logger.Errorf("Failed to get logs for service '%v' from k8s: %v", err)
return
}
// @todo: this might actually not run before podLogStream starts
// and might cause out of order log retrieval at the receiving end.
// A better approach would probably to suppor this inside the `klog.Stream` method.
for _, record := range records {
stream.Chan() <- record
}
}()
}
return stream, nil
}
type kubeStream struct {
// the k8s log stream
stream chan runtime.LogRecord
// the stop chan
stop chan bool
}
func (k *kubeStream) Chan() chan runtime.LogRecord {
return k.stream
}
func (k *kubeStream) Stop() error {
select {
case <-k.stop:
return nil
default:
close(k.stop)
close(k.stream)
}
return nil
}
// Creates a service
func (k *kubernetes) Create(s *runtime.Service, opts ...runtime.CreateOption) error {
k.Lock()

View File

@@ -0,0 +1,170 @@
// Package kubernetes taken from https://github.com/micro/go-micro/blob/master/debug/log/kubernetes/kubernetes.go
// There are some modifications compared to the other files as
// this package doesn't provide write functionality.
// With the write functionality gone, structured logs also go away.
package kubernetes
import (
"bufio"
"fmt"
"os"
"strconv"
"time"
"github.com/micro/go-micro/v2/runtime"
"github.com/micro/go-micro/v2/util/kubernetes/client"
)
type klog struct {
client client.Client
serviceName string
options runtime.LogsOptions
}
func (k *klog) podLogStream(podName string, stream *kubeStream) {
p := make(map[string]string)
p["follow"] = "true"
// get the logs for the pod
body, err := k.client.Log(&client.Resource{
Name: podName,
Kind: "pod",
}, client.LogParams(p))
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
return
}
s := bufio.NewScanner(body)
defer body.Close()
for {
select {
case <-stream.stop:
return
default:
if s.Scan() {
record := runtime.LogRecord{
Message: s.Text(),
}
stream.stream <- record
} else {
// TODO: is there a blocking call
// rather than a sleep loop?
time.Sleep(time.Second)
}
}
}
}
func (k *klog) getMatchingPods() ([]string, error) {
r := &client.Resource{
Kind: "pod",
Value: new(client.PodList),
}
l := make(map[string]string)
l["name"] = client.Format(k.serviceName)
// TODO: specify micro:service
// l["micro"] = "service"
if err := k.client.Get(r, l); err != nil {
return nil, err
}
var matches []string
for _, p := range r.Value.(*client.PodList).Items {
// find labels that match the name
if p.Metadata.Labels["name"] == client.Format(k.serviceName) {
matches = append(matches, p.Metadata.Name)
}
}
return matches, nil
}
func (k *klog) Read() ([]runtime.LogRecord, error) {
pods, err := k.getMatchingPods()
if err != nil {
return nil, err
}
var records []runtime.LogRecord
for _, pod := range pods {
logParams := make(map[string]string)
//if !opts.Since.Equal(time.Time{}) {
// logParams["sinceSeconds"] = strconv.Itoa(int(time.Since(opts.Since).Seconds()))
//}
if k.options.Count != 0 {
logParams["tailLines"] = strconv.Itoa(int(k.options.Count))
}
if k.options.Stream == true {
logParams["follow"] = "true"
}
logs, err := k.client.Log(&client.Resource{
Name: pod,
Kind: "pod",
}, client.LogParams(logParams))
if err != nil {
return nil, err
}
defer logs.Close()
s := bufio.NewScanner(logs)
for s.Scan() {
record := runtime.LogRecord{
Message: s.Text(),
}
// record.Metadata["pod"] = pod
records = append(records, record)
}
}
// sort the records
// sort.Slice(records, func(i, j int) bool { return records[i].Timestamp.Before(records[j].Timestamp) })
return records, nil
}
func (k *klog) Stream() (runtime.LogStream, error) {
// find the matching pods
pods, err := k.getMatchingPods()
if err != nil {
return nil, err
}
stream := &kubeStream{
stream: make(chan runtime.LogRecord),
stop: make(chan bool),
}
// stream from the individual pods
for _, pod := range pods {
go k.podLogStream(pod, stream)
}
return stream, nil
}
// NewLog returns a configured Kubernetes logger
func newLog(client client.Client, serviceName string, opts ...runtime.LogsOption) *klog {
klog := &klog{
serviceName: serviceName,
client: client,
}
for _, o := range opts {
o(&klog.options)
}
return klog
}

View File

@@ -149,3 +149,28 @@ func ReadType(t string) ReadOption {
o.Type = t
}
}
// LogsOption configures runtime logging
type LogsOption func(o *LogsOptions)
// LogsOptions configure runtime logging
type LogsOptions struct {
// How many existing lines to show
Count int64
// Stream new lines?
Stream bool
}
// LogsExistingCount confiures how many existing lines to show
func LogsCount(count int64) LogsOption {
return func(l *LogsOptions) {
l.Count = count
}
}
// LogsStream configures whether to stream new lines
func LogsStream(stream bool) LogsOption {
return func(l *LogsOptions) {
l.Stream = stream
}
}

View File

@@ -35,6 +35,19 @@ type Runtime interface {
Start() error
// Stop shuts down the runtime
Stop() error
// Logs
Logs(*Service, ...LogsOption) (LogStream, error)
}
// Stream returns a log stream
type LogStream interface {
Chan() chan LogRecord
Stop() error
}
type LogRecord struct {
Message string
Metadata map[string]string
}
// Scheduler is a runtime service scheduler

View File

@@ -1,15 +1,11 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: runtime/service/proto/runtime.proto
// source: micro/go-micro/runtime/service/proto/runtime.proto
package go_micro_runtime
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
@@ -42,7 +38,7 @@ func (m *Service) Reset() { *m = Service{} }
func (m *Service) String() string { return proto.CompactTextString(m) }
func (*Service) ProtoMessage() {}
func (*Service) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{0}
return fileDescriptor_4bc91a8efec81434, []int{0}
}
func (m *Service) XXX_Unmarshal(b []byte) error {
@@ -105,7 +101,7 @@ func (m *Event) Reset() { *m = Event{} }
func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{1}
return fileDescriptor_4bc91a8efec81434, []int{1}
}
func (m *Event) XXX_Unmarshal(b []byte) error {
@@ -176,7 +172,7 @@ func (m *CreateOptions) Reset() { *m = CreateOptions{} }
func (m *CreateOptions) String() string { return proto.CompactTextString(m) }
func (*CreateOptions) ProtoMessage() {}
func (*CreateOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{2}
return fileDescriptor_4bc91a8efec81434, []int{2}
}
func (m *CreateOptions) XXX_Unmarshal(b []byte) error {
@@ -251,7 +247,7 @@ func (m *CreateRequest) Reset() { *m = CreateRequest{} }
func (m *CreateRequest) String() string { return proto.CompactTextString(m) }
func (*CreateRequest) ProtoMessage() {}
func (*CreateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{3}
return fileDescriptor_4bc91a8efec81434, []int{3}
}
func (m *CreateRequest) XXX_Unmarshal(b []byte) error {
@@ -296,7 +292,7 @@ func (m *CreateResponse) Reset() { *m = CreateResponse{} }
func (m *CreateResponse) String() string { return proto.CompactTextString(m) }
func (*CreateResponse) ProtoMessage() {}
func (*CreateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{4}
return fileDescriptor_4bc91a8efec81434, []int{4}
}
func (m *CreateResponse) XXX_Unmarshal(b []byte) error {
@@ -333,7 +329,7 @@ func (m *ReadOptions) Reset() { *m = ReadOptions{} }
func (m *ReadOptions) String() string { return proto.CompactTextString(m) }
func (*ReadOptions) ProtoMessage() {}
func (*ReadOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{5}
return fileDescriptor_4bc91a8efec81434, []int{5}
}
func (m *ReadOptions) XXX_Unmarshal(b []byte) error {
@@ -386,7 +382,7 @@ func (m *ReadRequest) Reset() { *m = ReadRequest{} }
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
func (*ReadRequest) ProtoMessage() {}
func (*ReadRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{6}
return fileDescriptor_4bc91a8efec81434, []int{6}
}
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
@@ -425,7 +421,7 @@ func (m *ReadResponse) Reset() { *m = ReadResponse{} }
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
func (*ReadResponse) ProtoMessage() {}
func (*ReadResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{7}
return fileDescriptor_4bc91a8efec81434, []int{7}
}
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
@@ -464,7 +460,7 @@ func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteRequest) ProtoMessage() {}
func (*DeleteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{8}
return fileDescriptor_4bc91a8efec81434, []int{8}
}
func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
@@ -502,7 +498,7 @@ func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteResponse) ProtoMessage() {}
func (*DeleteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{9}
return fileDescriptor_4bc91a8efec81434, []int{9}
}
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
@@ -534,7 +530,7 @@ func (m *UpdateRequest) Reset() { *m = UpdateRequest{} }
func (m *UpdateRequest) String() string { return proto.CompactTextString(m) }
func (*UpdateRequest) ProtoMessage() {}
func (*UpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{10}
return fileDescriptor_4bc91a8efec81434, []int{10}
}
func (m *UpdateRequest) XXX_Unmarshal(b []byte) error {
@@ -572,7 +568,7 @@ func (m *UpdateResponse) Reset() { *m = UpdateResponse{} }
func (m *UpdateResponse) String() string { return proto.CompactTextString(m) }
func (*UpdateResponse) ProtoMessage() {}
func (*UpdateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{11}
return fileDescriptor_4bc91a8efec81434, []int{11}
}
func (m *UpdateResponse) XXX_Unmarshal(b []byte) error {
@@ -603,7 +599,7 @@ func (m *ListRequest) Reset() { *m = ListRequest{} }
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
func (*ListRequest) ProtoMessage() {}
func (*ListRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{12}
return fileDescriptor_4bc91a8efec81434, []int{12}
}
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
@@ -635,7 +631,7 @@ func (m *ListResponse) Reset() { *m = ListResponse{} }
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
func (*ListResponse) ProtoMessage() {}
func (*ListResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_2434d8152598889b, []int{13}
return fileDescriptor_4bc91a8efec81434, []int{13}
}
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
@@ -663,6 +659,133 @@ func (m *ListResponse) GetServices() []*Service {
return nil
}
type LogsRequest struct {
// service to request logs for
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
// stream records continuously
Stream bool `protobuf:"varint,2,opt,name=stream,proto3" json:"stream,omitempty"`
// count of records to request
Count int64 `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"`
// relative time in seconds
// before the current time
// from which to show logs
Since int64 `protobuf:"varint,4,opt,name=since,proto3" json:"since,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LogsRequest) Reset() { *m = LogsRequest{} }
func (m *LogsRequest) String() string { return proto.CompactTextString(m) }
func (*LogsRequest) ProtoMessage() {}
func (*LogsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_4bc91a8efec81434, []int{14}
}
func (m *LogsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LogsRequest.Unmarshal(m, b)
}
func (m *LogsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LogsRequest.Marshal(b, m, deterministic)
}
func (m *LogsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_LogsRequest.Merge(m, src)
}
func (m *LogsRequest) XXX_Size() int {
return xxx_messageInfo_LogsRequest.Size(m)
}
func (m *LogsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_LogsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_LogsRequest proto.InternalMessageInfo
func (m *LogsRequest) GetService() string {
if m != nil {
return m.Service
}
return ""
}
func (m *LogsRequest) GetStream() bool {
if m != nil {
return m.Stream
}
return false
}
func (m *LogsRequest) GetCount() int64 {
if m != nil {
return m.Count
}
return 0
}
func (m *LogsRequest) GetSince() int64 {
if m != nil {
return m.Since
}
return 0
}
type LogRecord struct {
// timestamp of log record
Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// record metadata
Metadata map[string]string `protobuf:"bytes,2,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// message
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LogRecord) Reset() { *m = LogRecord{} }
func (m *LogRecord) String() string { return proto.CompactTextString(m) }
func (*LogRecord) ProtoMessage() {}
func (*LogRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_4bc91a8efec81434, []int{15}
}
func (m *LogRecord) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LogRecord.Unmarshal(m, b)
}
func (m *LogRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LogRecord.Marshal(b, m, deterministic)
}
func (m *LogRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_LogRecord.Merge(m, src)
}
func (m *LogRecord) XXX_Size() int {
return xxx_messageInfo_LogRecord.Size(m)
}
func (m *LogRecord) XXX_DiscardUnknown() {
xxx_messageInfo_LogRecord.DiscardUnknown(m)
}
var xxx_messageInfo_LogRecord proto.InternalMessageInfo
func (m *LogRecord) GetTimestamp() int64 {
if m != nil {
return m.Timestamp
}
return 0
}
func (m *LogRecord) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
}
return nil
}
func (m *LogRecord) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func init() {
proto.RegisterType((*Service)(nil), "go.micro.runtime.Service")
proto.RegisterMapType((map[string]string)(nil), "go.micro.runtime.Service.MetadataEntry")
@@ -679,271 +802,57 @@ func init() {
proto.RegisterType((*UpdateResponse)(nil), "go.micro.runtime.UpdateResponse")
proto.RegisterType((*ListRequest)(nil), "go.micro.runtime.ListRequest")
proto.RegisterType((*ListResponse)(nil), "go.micro.runtime.ListResponse")
proto.RegisterType((*LogsRequest)(nil), "go.micro.runtime.LogsRequest")
proto.RegisterType((*LogRecord)(nil), "go.micro.runtime.LogRecord")
proto.RegisterMapType((map[string]string)(nil), "go.micro.runtime.LogRecord.MetadataEntry")
}
func init() {
proto.RegisterFile("runtime/service/proto/runtime.proto", fileDescriptor_2434d8152598889b)
proto.RegisterFile("micro/go-micro/runtime/service/proto/runtime.proto", fileDescriptor_4bc91a8efec81434)
}
var fileDescriptor_2434d8152598889b = []byte{
// 548 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x49, 0x6f, 0xd3, 0x40,
0x14, 0xae, 0xe3, 0x2c, 0xed, 0x0b, 0x46, 0xd1, 0xa8, 0x42, 0xa6, 0x62, 0x89, 0xcc, 0x81, 0x9e,
0x1c, 0x29, 0x15, 0x62, 0x3b, 0x36, 0x81, 0x0b, 0x11, 0x92, 0x51, 0x7f, 0xc0, 0x90, 0x3c, 0x45,
0x16, 0xb5, 0xc7, 0x78, 0xc6, 0x96, 0x72, 0xe2, 0xca, 0x95, 0x9f, 0xc6, 0x3f, 0x42, 0xb3, 0x79,
0x49, 0x6d, 0x2e, 0xb9, 0xbd, 0xf7, 0xe6, 0xcd, 0x37, 0xdf, 0x62, 0x19, 0x5e, 0xe5, 0x45, 0x2a,
0xe2, 0x04, 0x17, 0x1c, 0xf3, 0x32, 0xde, 0xe2, 0x22, 0xcb, 0x99, 0x60, 0x0b, 0x33, 0x0d, 0x55,
0x47, 0x66, 0x7b, 0x16, 0x26, 0xf1, 0x36, 0x67, 0xa1, 0x99, 0x07, 0x7f, 0x1d, 0x98, 0x7c, 0xd3,
0x37, 0x08, 0x81, 0x61, 0x4a, 0x13, 0xf4, 0x9d, 0xb9, 0x73, 0x7d, 0x11, 0xa9, 0x9a, 0xf8, 0x30,
0x29, 0x31, 0xe7, 0x31, 0x4b, 0xfd, 0x81, 0x1a, 0xdb, 0x96, 0x3c, 0x81, 0x31, 0x67, 0x45, 0xbe,
0x45, 0xdf, 0x55, 0x07, 0xa6, 0x23, 0xb7, 0x70, 0x9e, 0xa0, 0xa0, 0x3b, 0x2a, 0xa8, 0x3f, 0x9c,
0xbb, 0xd7, 0xd3, 0xe5, 0xeb, 0xf0, 0xf8, 0xd9, 0xd0, 0x3c, 0x19, 0x6e, 0xcc, 0xe6, 0x3a, 0x15,
0xf9, 0x21, 0xaa, 0x2e, 0x5e, 0x7d, 0x04, 0xaf, 0x75, 0x44, 0x66, 0xe0, 0xfe, 0xc0, 0x83, 0xa1,
0x26, 0x4b, 0x72, 0x09, 0xa3, 0x92, 0xde, 0x17, 0x68, 0x78, 0xe9, 0xe6, 0xc3, 0xe0, 0x9d, 0x13,
0x24, 0x30, 0x5a, 0x97, 0x98, 0x0a, 0x29, 0x48, 0x1c, 0xb2, 0x4a, 0x90, 0xac, 0xc9, 0x33, 0xb8,
0x90, 0x0c, 0xb8, 0xa0, 0x49, 0xa6, 0xae, 0xba, 0x51, 0x3d, 0x90, 0x72, 0x8d, 0x7f, 0x46, 0x95,
0x6d, 0x9b, 0x46, 0x0c, 0x5b, 0x46, 0x04, 0x7f, 0x1c, 0xf0, 0x6e, 0x73, 0xa4, 0x02, 0xbf, 0x66,
0x22, 0x66, 0x29, 0x97, 0xbb, 0x5b, 0x96, 0x24, 0x34, 0xdd, 0xf9, 0xce, 0xdc, 0x95, 0xbb, 0xa6,
0x95, 0x8c, 0x68, 0xbe, 0xe7, 0xfe, 0x40, 0x8d, 0x55, 0x2d, 0xa5, 0x61, 0x5a, 0xfa, 0xae, 0x1a,
0xc9, 0x52, 0x5a, 0xcb, 0x0a, 0x91, 0x15, 0xc2, 0x3c, 0x65, 0xba, 0x4a, 0xcf, 0xa8, 0xa1, 0xe7,
0x12, 0x46, 0x71, 0x42, 0xf7, 0xe8, 0x8f, 0xb5, 0x0d, 0xaa, 0x09, 0x7e, 0x59, 0x4a, 0x11, 0xfe,
0x2c, 0x90, 0x0b, 0x72, 0x53, 0x0b, 0x93, 0x6e, 0x4c, 0x97, 0x4f, 0x7b, 0x43, 0xa9, 0x35, 0xbf,
0x87, 0x09, 0xd3, 0x92, 0x94, 0x53, 0xd3, 0xe5, 0xcb, 0x87, 0x97, 0x5a, 0xca, 0x23, 0xbb, 0x1f,
0xcc, 0xe0, 0xb1, 0x25, 0xc0, 0x33, 0x96, 0x72, 0x0c, 0xee, 0x60, 0x1a, 0x21, 0xdd, 0x35, 0x3c,
0x6a, 0x12, 0xea, 0x76, 0xfa, 0xe8, 0x93, 0xb3, 0xfa, 0xdd, 0x5a, 0x7f, 0xf0, 0x49, 0xc3, 0x5a,
0x9d, 0x6f, 0x6b, 0xca, 0x5a, 0xe7, 0xf3, 0x87, 0x94, 0x1b, 0x34, 0x6a, 0xc2, 0x6b, 0x78, 0xa4,
0x71, 0x34, 0x5d, 0xf2, 0x06, 0xce, 0x0d, 0x21, 0xae, 0x42, 0xfc, 0xaf, 0x63, 0xd5, 0x6a, 0xb0,
0x02, 0x6f, 0x85, 0xf7, 0x78, 0x9a, 0xf1, 0xd2, 0x3d, 0x8b, 0x62, 0xdc, 0x5b, 0x81, 0x77, 0x97,
0xed, 0xe8, 0xe9, 0xb8, 0x16, 0xc5, 0xe0, 0x7a, 0x30, 0xfd, 0x12, 0x73, 0x61, 0x50, 0xa5, 0x0b,
0xba, 0x3d, 0xc9, 0x85, 0xe5, 0x6f, 0x17, 0x26, 0x91, 0x3e, 0x25, 0x1b, 0x18, 0xeb, 0x2f, 0x81,
0xf4, 0x7e, 0x3d, 0xe6, 0xf5, 0xab, 0x79, 0xff, 0x82, 0xa1, 0x7b, 0x46, 0x3e, 0xc3, 0x50, 0xe6,
0x44, 0x7a, 0x72, 0xb5, 0x50, 0x2f, 0xfa, 0x8e, 0x2b, 0xa0, 0x0d, 0x8c, 0xb5, 0xc7, 0x5d, 0xbc,
0x5a, 0x19, 0x76, 0xf1, 0x3a, 0x8a, 0x47, 0xc1, 0x69, 0x6b, 0xbb, 0xe0, 0x5a, 0xd1, 0x75, 0xc1,
0x1d, 0xa5, 0xa2, 0x64, 0xca, 0x20, 0xba, 0x64, 0x36, 0xf2, 0xea, 0x92, 0xd9, 0xcc, 0x2f, 0x38,
0xfb, 0x3e, 0x56, 0x7f, 0xfe, 0x9b, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x01, 0xa4, 0x43,
0x20, 0x06, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// RuntimeClient is the client API for Runtime service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type RuntimeClient interface {
Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error)
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error)
Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*UpdateResponse, error)
List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
}
type runtimeClient struct {
cc *grpc.ClientConn
}
func NewRuntimeClient(cc *grpc.ClientConn) RuntimeClient {
return &runtimeClient{cc}
}
func (c *runtimeClient) Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error) {
out := new(CreateResponse)
err := c.cc.Invoke(ctx, "/go.micro.runtime.Runtime/Create", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *runtimeClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
out := new(ReadResponse)
err := c.cc.Invoke(ctx, "/go.micro.runtime.Runtime/Read", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *runtimeClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) {
out := new(DeleteResponse)
err := c.cc.Invoke(ctx, "/go.micro.runtime.Runtime/Delete", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *runtimeClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*UpdateResponse, error) {
out := new(UpdateResponse)
err := c.cc.Invoke(ctx, "/go.micro.runtime.Runtime/Update", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *runtimeClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
out := new(ListResponse)
err := c.cc.Invoke(ctx, "/go.micro.runtime.Runtime/List", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// RuntimeServer is the server API for Runtime service.
type RuntimeServer interface {
Create(context.Context, *CreateRequest) (*CreateResponse, error)
Read(context.Context, *ReadRequest) (*ReadResponse, error)
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
Update(context.Context, *UpdateRequest) (*UpdateResponse, error)
List(context.Context, *ListRequest) (*ListResponse, error)
}
// UnimplementedRuntimeServer can be embedded to have forward compatible implementations.
type UnimplementedRuntimeServer struct {
}
func (*UnimplementedRuntimeServer) Create(ctx context.Context, req *CreateRequest) (*CreateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
}
func (*UnimplementedRuntimeServer) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
}
func (*UnimplementedRuntimeServer) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
}
func (*UnimplementedRuntimeServer) Update(ctx context.Context, req *UpdateRequest) (*UpdateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Update not implemented")
}
func (*UnimplementedRuntimeServer) List(ctx context.Context, req *ListRequest) (*ListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method List not implemented")
}
func RegisterRuntimeServer(s *grpc.Server, srv RuntimeServer) {
s.RegisterService(&_Runtime_serviceDesc, srv)
}
func _Runtime_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RuntimeServer).Create(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.runtime.Runtime/Create",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RuntimeServer).Create(ctx, req.(*CreateRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Runtime_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReadRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RuntimeServer).Read(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.runtime.Runtime/Read",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RuntimeServer).Read(ctx, req.(*ReadRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Runtime_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RuntimeServer).Delete(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.runtime.Runtime/Delete",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RuntimeServer).Delete(ctx, req.(*DeleteRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Runtime_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RuntimeServer).Update(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.runtime.Runtime/Update",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RuntimeServer).Update(ctx, req.(*UpdateRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Runtime_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RuntimeServer).List(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.runtime.Runtime/List",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RuntimeServer).List(ctx, req.(*ListRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Runtime_serviceDesc = grpc.ServiceDesc{
ServiceName: "go.micro.runtime.Runtime",
HandlerType: (*RuntimeServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Create",
Handler: _Runtime_Create_Handler,
},
{
MethodName: "Read",
Handler: _Runtime_Read_Handler,
},
{
MethodName: "Delete",
Handler: _Runtime_Delete_Handler,
},
{
MethodName: "Update",
Handler: _Runtime_Update_Handler,
},
{
MethodName: "List",
Handler: _Runtime_List_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "runtime/service/proto/runtime.proto",
var fileDescriptor_4bc91a8efec81434 = []byte{
// 663 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcb, 0x6e, 0xd3, 0x40,
0x14, 0xad, 0xe3, 0x3c, 0xda, 0x6b, 0x82, 0xaa, 0x51, 0x85, 0x4c, 0x79, 0x45, 0xde, 0x50, 0x16,
0xb8, 0x28, 0x15, 0xe2, 0xb5, 0x6c, 0x53, 0x36, 0x8d, 0x90, 0x8c, 0xfa, 0x01, 0x83, 0x73, 0x65,
0x59, 0xad, 0x3d, 0xc6, 0x33, 0x8e, 0x94, 0x15, 0xdf, 0xc0, 0x57, 0xb1, 0x85, 0x3f, 0x42, 0xf3,
0xf0, 0x2b, 0xb1, 0xbb, 0xc9, 0x6e, 0xee, 0xe4, 0xce, 0xf1, 0x39, 0x67, 0xce, 0x9d, 0xc0, 0x3c,
0x89, 0xc3, 0x9c, 0x9d, 0x47, 0xec, 0xad, 0x5e, 0xe4, 0x45, 0x2a, 0xe2, 0x04, 0xcf, 0x39, 0xe6,
0xeb, 0x38, 0xc4, 0xf3, 0x2c, 0x67, 0xa2, 0xda, 0xf5, 0x55, 0x45, 0x8e, 0x23, 0xe6, 0xab, 0x6e,
0xdf, 0xec, 0x7b, 0xff, 0x2c, 0x98, 0x7c, 0xd7, 0x27, 0x08, 0x81, 0x61, 0x4a, 0x13, 0x74, 0xad,
0x99, 0x75, 0x76, 0x14, 0xa8, 0x35, 0x71, 0x61, 0xb2, 0xc6, 0x9c, 0xc7, 0x2c, 0x75, 0x07, 0x6a,
0xbb, 0x2c, 0xc9, 0x13, 0x18, 0x73, 0x56, 0xe4, 0x21, 0xba, 0xb6, 0xfa, 0xc1, 0x54, 0xe4, 0x12,
0x0e, 0x13, 0x14, 0x74, 0x45, 0x05, 0x75, 0x87, 0x33, 0xfb, 0xcc, 0x99, 0xbf, 0xf6, 0xb7, 0x3f,
0xeb, 0x9b, 0x4f, 0xfa, 0x4b, 0xd3, 0xb9, 0x48, 0x45, 0xbe, 0x09, 0xaa, 0x83, 0xa7, 0x5f, 0x60,
0xda, 0xfa, 0x89, 0x1c, 0x83, 0x7d, 0x87, 0x1b, 0x43, 0x4d, 0x2e, 0xc9, 0x09, 0x8c, 0xd6, 0xf4,
0xbe, 0x40, 0xc3, 0x4b, 0x17, 0x9f, 0x07, 0x1f, 0x2d, 0x2f, 0x81, 0xd1, 0x62, 0x8d, 0xa9, 0x90,
0x82, 0xc4, 0x26, 0xab, 0x04, 0xc9, 0x35, 0x79, 0x0e, 0x47, 0x92, 0x01, 0x17, 0x34, 0xc9, 0xd4,
0x51, 0x3b, 0xa8, 0x37, 0xa4, 0x5c, 0xe3, 0x9f, 0x51, 0x55, 0x96, 0x4d, 0x23, 0x86, 0x2d, 0x23,
0xbc, 0xdf, 0x16, 0x4c, 0x2f, 0x73, 0xa4, 0x02, 0xbf, 0x65, 0x22, 0x66, 0x29, 0x97, 0xbd, 0x21,
0x4b, 0x12, 0x9a, 0xae, 0x5c, 0x6b, 0x66, 0xcb, 0x5e, 0x53, 0x4a, 0x46, 0x34, 0x8f, 0xb8, 0x3b,
0x50, 0xdb, 0x6a, 0x2d, 0xa5, 0x61, 0xba, 0x76, 0x6d, 0xb5, 0x25, 0x97, 0xd2, 0x5a, 0x56, 0x88,
0xac, 0x10, 0xe6, 0x53, 0xa6, 0xaa, 0xf4, 0x8c, 0x1a, 0x7a, 0x4e, 0x60, 0x14, 0x27, 0x34, 0x42,
0x77, 0xac, 0x6d, 0x50, 0x85, 0xf7, 0xab, 0xa4, 0x14, 0xe0, 0xcf, 0x02, 0xb9, 0x20, 0x17, 0xb5,
0x30, 0xe9, 0x86, 0x33, 0x7f, 0xda, 0x7b, 0x29, 0xb5, 0xe6, 0x4f, 0x30, 0x61, 0x5a, 0x92, 0x72,
0xca, 0x99, 0xbf, 0xda, 0x3d, 0xd4, 0x52, 0x1e, 0x94, 0xfd, 0xde, 0x31, 0x3c, 0x2e, 0x09, 0xf0,
0x8c, 0xa5, 0x1c, 0xbd, 0x5b, 0x70, 0x02, 0xa4, 0xab, 0x86, 0x47, 0x4d, 0x42, 0xdd, 0x4e, 0x6f,
0x45, 0xae, 0xd4, 0x6f, 0xd7, 0xfa, 0xbd, 0x6b, 0x0d, 0x5b, 0xea, 0xfc, 0x50, 0x53, 0xd6, 0x3a,
0x5f, 0xec, 0x52, 0x6e, 0xd0, 0xa8, 0x09, 0x2f, 0xe0, 0x91, 0xc6, 0xd1, 0x74, 0xc9, 0x7b, 0x38,
0x34, 0x84, 0xb8, 0xba, 0xc4, 0x07, 0x1d, 0xab, 0x5a, 0xbd, 0x2b, 0x98, 0x5e, 0xe1, 0x3d, 0xee,
0x67, 0xbc, 0x74, 0xaf, 0x44, 0x31, 0xee, 0x5d, 0xc1, 0xf4, 0x36, 0x5b, 0xd1, 0xfd, 0x71, 0x4b,
0x14, 0x83, 0x3b, 0x05, 0xe7, 0x26, 0xe6, 0xc2, 0xa0, 0x4a, 0x17, 0x74, 0xb9, 0x9f, 0x0b, 0x77,
0xe0, 0xdc, 0xb0, 0x88, 0x97, 0x5c, 0xfb, 0xef, 0x5a, 0x3e, 0x22, 0x22, 0x47, 0x9a, 0xa8, 0xab,
0x3e, 0x0c, 0x4c, 0x25, 0x53, 0x1d, 0xb2, 0x22, 0x15, 0xea, 0xaa, 0xed, 0x40, 0x17, 0x72, 0x97,
0xc7, 0x69, 0x88, 0x6a, 0x2c, 0xec, 0x40, 0x17, 0xde, 0x1f, 0x0b, 0x8e, 0x6e, 0x58, 0x14, 0x60,
0xc8, 0xf2, 0x55, 0x7b, 0xbe, 0xad, 0xed, 0xf9, 0x5e, 0x34, 0x1e, 0xa7, 0x81, 0xd2, 0xf3, 0x66,
0x57, 0x4f, 0x05, 0xd6, 0xf7, 0x3c, 0x49, 0x41, 0x09, 0x72, 0x2e, 0xc7, 0xce, 0x3c, 0x13, 0xa6,
0xdc, 0xeb, 0xe1, 0x9a, 0xff, 0xb5, 0x61, 0x12, 0x68, 0x12, 0x64, 0x09, 0x63, 0x3d, 0x40, 0xa4,
0x77, 0xe8, 0x8c, 0xbd, 0xa7, 0xb3, 0xfe, 0x06, 0x73, 0xcb, 0x07, 0xe4, 0x2b, 0x0c, 0x65, 0xbc,
0x49, 0xcf, 0x38, 0x94, 0x50, 0x2f, 0xfb, 0x7e, 0xae, 0x80, 0x96, 0x30, 0xd6, 0xd1, 0xec, 0xe2,
0xd5, 0x8a, 0x7e, 0x17, 0xaf, 0xad, 0x54, 0x2b, 0x38, 0x9d, 0xc8, 0x2e, 0xb8, 0x56, 0xe2, 0xbb,
0xe0, 0xb6, 0xc2, 0xac, 0x64, 0xca, 0xfc, 0x76, 0xc9, 0x6c, 0xc4, 0xbc, 0x4b, 0x66, 0x33, 0xf6,
0xde, 0x01, 0xb9, 0x86, 0xa1, 0x4c, 0x70, 0x27, 0x50, 0x9d, 0xec, 0xd3, 0x67, 0x0f, 0xa4, 0xc7,
0x3b, 0x78, 0x67, 0xfd, 0x18, 0xab, 0x3f, 0xde, 0x8b, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x17,
0xe1, 0xab, 0x77, 0xae, 0x07, 0x00, 0x00,
}

View File

@@ -1,5 +1,5 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: runtime/service/proto/runtime.proto
// source: micro/go-micro/runtime/service/proto/runtime.proto
package go_micro_runtime
@@ -39,6 +39,7 @@ type RuntimeService interface {
Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error)
Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error)
List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
Logs(ctx context.Context, in *LogsRequest, opts ...client.CallOption) (Runtime_LogsService, error)
}
type runtimeService struct {
@@ -103,6 +104,55 @@ func (c *runtimeService) List(ctx context.Context, in *ListRequest, opts ...clie
return out, nil
}
func (c *runtimeService) Logs(ctx context.Context, in *LogsRequest, opts ...client.CallOption) (Runtime_LogsService, error) {
req := c.c.NewRequest(c.name, "Runtime.Logs", &LogsRequest{})
stream, err := c.c.Stream(ctx, req, opts...)
if err != nil {
return nil, err
}
if err := stream.Send(in); err != nil {
return nil, err
}
return &runtimeServiceLogs{stream}, nil
}
type Runtime_LogsService interface {
Context() context.Context
SendMsg(interface{}) error
RecvMsg(interface{}) error
Close() error
Recv() (*LogRecord, error)
}
type runtimeServiceLogs struct {
stream client.Stream
}
func (x *runtimeServiceLogs) Close() error {
return x.stream.Close()
}
func (x *runtimeServiceLogs) Context() context.Context {
return x.stream.Context()
}
func (x *runtimeServiceLogs) SendMsg(m interface{}) error {
return x.stream.Send(m)
}
func (x *runtimeServiceLogs) RecvMsg(m interface{}) error {
return x.stream.Recv(m)
}
func (x *runtimeServiceLogs) Recv() (*LogRecord, error) {
m := new(LogRecord)
err := x.stream.Recv(m)
if err != nil {
return nil, err
}
return m, nil
}
// Server API for Runtime service
type RuntimeHandler interface {
@@ -111,6 +161,7 @@ type RuntimeHandler interface {
Delete(context.Context, *DeleteRequest, *DeleteResponse) error
Update(context.Context, *UpdateRequest, *UpdateResponse) error
List(context.Context, *ListRequest, *ListResponse) error
Logs(context.Context, *LogsRequest, Runtime_LogsStream) error
}
func RegisterRuntimeHandler(s server.Server, hdlr RuntimeHandler, opts ...server.HandlerOption) error {
@@ -120,6 +171,7 @@ func RegisterRuntimeHandler(s server.Server, hdlr RuntimeHandler, opts ...server
Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error
Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error
List(ctx context.Context, in *ListRequest, out *ListResponse) error
Logs(ctx context.Context, stream server.Stream) error
}
type Runtime struct {
runtime
@@ -151,3 +203,43 @@ func (h *runtimeHandler) Update(ctx context.Context, in *UpdateRequest, out *Upd
func (h *runtimeHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error {
return h.RuntimeHandler.List(ctx, in, out)
}
func (h *runtimeHandler) Logs(ctx context.Context, stream server.Stream) error {
m := new(LogsRequest)
if err := stream.Recv(m); err != nil {
return err
}
return h.RuntimeHandler.Logs(ctx, m, &runtimeLogsStream{stream})
}
type Runtime_LogsStream interface {
Context() context.Context
SendMsg(interface{}) error
RecvMsg(interface{}) error
Close() error
Send(*LogRecord) error
}
type runtimeLogsStream struct {
stream server.Stream
}
func (x *runtimeLogsStream) Close() error {
return x.stream.Close()
}
func (x *runtimeLogsStream) Context() context.Context {
return x.stream.Context()
}
func (x *runtimeLogsStream) SendMsg(m interface{}) error {
return x.stream.Send(m)
}
func (x *runtimeLogsStream) RecvMsg(m interface{}) error {
return x.stream.Recv(m)
}
func (x *runtimeLogsStream) Send(m *LogRecord) error {
return x.stream.Send(m)
}

View File

@@ -8,6 +8,7 @@ service Runtime {
rpc Delete(DeleteRequest) returns (DeleteResponse) {};
rpc Update(UpdateRequest) returns (UpdateResponse) {};
rpc List(ListRequest) returns (ListResponse) {};
rpc Logs(LogsRequest) returns (stream LogRecord) {};
}
message Service {
@@ -84,3 +85,26 @@ message ListRequest {}
message ListResponse {
repeated Service services = 1;
}
message LogsRequest{
// service to request logs for
string service = 1;
// stream records continuously
bool stream = 2;
// count of records to request
int64 count = 3;
// relative time in seconds
// before the current time
// from which to show logs
int64 since = 4;
}
message LogRecord {
// timestamp of log record
int64 timestamp = 1;
// record metadata
map<string,string> metadata = 2;
// message
string message = 3;
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/runtime"
pb "github.com/micro/go-micro/v2/runtime/service/proto"
"github.com/micro/go-micro/v2/util/log"
)
type svc struct {
@@ -64,6 +65,53 @@ func (s *svc) Create(svc *runtime.Service, opts ...runtime.CreateOption) error {
return nil
}
func (s *svc) Logs(service *runtime.Service, options ...runtime.LogsOption) (runtime.LogStream, error) {
ls, err := s.runtime.Logs(context.Background(), &pb.LogsRequest{
Service: service.Name,
Stream: true,
Count: 10, // @todo pass in actual options
})
if err != nil {
return nil, err
}
logStream := &serviceLogStream{
service: service.Name,
stream: make(chan runtime.LogRecord),
stop: make(chan bool),
}
go func() {
for {
record := runtime.LogRecord{}
err := ls.RecvMsg(&record)
if err != nil {
log.Error(err)
}
logStream.stream <- record
}
}()
return logStream, nil
}
type serviceLogStream struct {
service string
stream chan runtime.LogRecord
stop chan bool
}
func (l *serviceLogStream) Chan() chan runtime.LogRecord {
return l.stream
}
func (l *serviceLogStream) Stop() error {
select {
case <-l.stop:
return nil
default:
close(l.stop)
}
return nil
}
// Read returns the service with the given name from the runtime
func (s *svc) Read(opts ...runtime.ReadOption) ([]*runtime.Service, error) {
options := runtime.ReadOptions{}