mirror of
https://github.com/golang/go
synced 2024-11-18 18:44:42 -07:00
internal/jsonrpc2: move stats and logging across to gopls
Change-Id: I718ad6075028e922a1a046b22fd01a1315421be1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/186297 Run-TryBot: Ian Cottrell <iancottrell@google.com> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
0b5a7f81db
commit
502543d2ed
@ -11,14 +11,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/telemetry"
|
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
|
||||||
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Conn is a JSON RPC 2 client server connection.
|
// Conn is a JSON RPC 2 client server connection.
|
||||||
@ -55,47 +49,6 @@ type Request struct {
|
|||||||
WireRequest
|
WireRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
type rpcStats struct {
|
|
||||||
server bool
|
|
||||||
method string
|
|
||||||
close func()
|
|
||||||
start time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func start(ctx context.Context, server bool, method string, id *ID) (context.Context, *rpcStats) {
|
|
||||||
if method == "" {
|
|
||||||
panic("no method in rpc stats")
|
|
||||||
}
|
|
||||||
s := &rpcStats{
|
|
||||||
server: server,
|
|
||||||
method: method,
|
|
||||||
start: time.Now(),
|
|
||||||
}
|
|
||||||
mode := telemetry.Outbound
|
|
||||||
if server {
|
|
||||||
mode = telemetry.Inbound
|
|
||||||
}
|
|
||||||
ctx, s.close = trace.StartSpan(ctx, method,
|
|
||||||
tag.Tag{Key: telemetry.Method, Value: method},
|
|
||||||
tag.Tag{Key: telemetry.RPCDirection, Value: mode},
|
|
||||||
tag.Tag{Key: telemetry.RPCID, Value: id},
|
|
||||||
)
|
|
||||||
telemetry.Started.Record(ctx, 1)
|
|
||||||
return ctx, s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *rpcStats) end(ctx context.Context, err *error) {
|
|
||||||
if err != nil && *err != nil {
|
|
||||||
ctx = telemetry.StatusCode.With(ctx, "ERROR")
|
|
||||||
} else {
|
|
||||||
ctx = telemetry.StatusCode.With(ctx, "OK")
|
|
||||||
}
|
|
||||||
elapsedTime := time.Since(s.start)
|
|
||||||
latencyMillis := float64(elapsedTime) / float64(time.Millisecond)
|
|
||||||
telemetry.Latency.Record(ctx, latencyMillis)
|
|
||||||
s.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrorf builds a Error struct for the suppied message and code.
|
// NewErrorf builds a Error struct for the suppied message and code.
|
||||||
// If args is not empty, message and args will be passed to Sprintf.
|
// If args is not empty, message and args will be passed to Sprintf.
|
||||||
func NewErrorf(code int64, format string, args ...interface{}) *Error {
|
func NewErrorf(code int64, format string, args ...interface{}) *Error {
|
||||||
@ -451,49 +404,3 @@ func marshalToRaw(obj interface{}) (*json.RawMessage, error) {
|
|||||||
raw := json.RawMessage(data)
|
raw := json.RawMessage(data)
|
||||||
return &raw, nil
|
return &raw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type statsKeyType int
|
|
||||||
|
|
||||||
const statsKey = statsKeyType(0)
|
|
||||||
|
|
||||||
type tracer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Deliver(ctx context.Context, r *Request, delivered bool) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Cancel(ctx context.Context, conn *Conn, id ID, cancelled bool) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Request(ctx context.Context, direction Direction, r *WireRequest) context.Context {
|
|
||||||
ctx, stats := start(ctx, direction == Receive, r.Method, r.ID)
|
|
||||||
ctx = context.WithValue(ctx, statsKey, stats)
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Response(ctx context.Context, direction Direction, r *WireResponse) context.Context {
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Done(ctx context.Context, err error) {
|
|
||||||
stats, ok := ctx.Value(statsKey).(*rpcStats)
|
|
||||||
if ok && stats != nil {
|
|
||||||
stats.end(ctx, &err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Read(ctx context.Context, bytes int64) context.Context {
|
|
||||||
telemetry.SentBytes.Record(ctx, bytes)
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Wrote(ctx context.Context, bytes int64) context.Context {
|
|
||||||
telemetry.ReceivedBytes.Record(ctx, bytes)
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tracer) Error(ctx context.Context, err error) {
|
|
||||||
log.Printf("%v", err)
|
|
||||||
}
|
|
||||||
|
@ -20,6 +20,9 @@ import (
|
|||||||
"golang.org/x/tools/internal/jsonrpc2"
|
"golang.org/x/tools/internal/jsonrpc2"
|
||||||
"golang.org/x/tools/internal/lsp"
|
"golang.org/x/tools/internal/lsp"
|
||||||
"golang.org/x/tools/internal/lsp/debug"
|
"golang.org/x/tools/internal/lsp/debug"
|
||||||
|
"golang.org/x/tools/internal/lsp/telemetry"
|
||||||
|
"golang.org/x/tools/internal/lsp/telemetry/tag"
|
||||||
|
"golang.org/x/tools/internal/lsp/telemetry/trace"
|
||||||
"golang.org/x/tools/internal/tool"
|
"golang.org/x/tools/internal/tool"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -246,3 +249,90 @@ func (h *handler) log(direction jsonrpc2.Direction, id *jsonrpc2.ID, elapsed tim
|
|||||||
fmt.Fprintf(outx, ".\r\nParams: %s%s", params, eol)
|
fmt.Fprintf(outx, ".\r\nParams: %s%s", params, eol)
|
||||||
fmt.Fprintf(h.out, "%s", outx.String())
|
fmt.Fprintf(h.out, "%s", outx.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type rpcStats struct {
|
||||||
|
server bool
|
||||||
|
method string
|
||||||
|
close func()
|
||||||
|
start time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func start(ctx context.Context, server bool, method string, id *ID) (context.Context, *rpcStats) {
|
||||||
|
if method == "" {
|
||||||
|
panic("no method in rpc stats")
|
||||||
|
}
|
||||||
|
s := &rpcStats{
|
||||||
|
server: server,
|
||||||
|
method: method,
|
||||||
|
start: time.Now(),
|
||||||
|
}
|
||||||
|
mode := telemetry.Outbound
|
||||||
|
if server {
|
||||||
|
mode = telemetry.Inbound
|
||||||
|
}
|
||||||
|
ctx, s.close = trace.StartSpan(ctx, method,
|
||||||
|
tag.Tag{Key: telemetry.Method, Value: method},
|
||||||
|
tag.Tag{Key: telemetry.RPCDirection, Value: mode},
|
||||||
|
tag.Tag{Key: telemetry.RPCID, Value: id},
|
||||||
|
)
|
||||||
|
telemetry.Started.Record(ctx, 1)
|
||||||
|
return ctx, s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *rpcStats) end(ctx context.Context, err *error) {
|
||||||
|
if err != nil && *err != nil {
|
||||||
|
ctx = telemetry.StatusCode.With(ctx, "ERROR")
|
||||||
|
} else {
|
||||||
|
ctx = telemetry.StatusCode.With(ctx, "OK")
|
||||||
|
}
|
||||||
|
elapsedTime := time.Since(s.start)
|
||||||
|
latencyMillis := float64(elapsedTime) / float64(time.Millisecond)
|
||||||
|
telemetry.Latency.Record(ctx, latencyMillis)
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type statsKeyType int
|
||||||
|
|
||||||
|
const statsKey = statsKeyType(0)
|
||||||
|
|
||||||
|
type tracer struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Deliver(ctx context.Context, r *Request, delivered bool) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Cancel(ctx context.Context, conn *Conn, id ID, cancelled bool) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Request(ctx context.Context, direction Direction, r *WireRequest) context.Context {
|
||||||
|
ctx, stats := start(ctx, direction == Receive, r.Method, r.ID)
|
||||||
|
ctx = context.WithValue(ctx, statsKey, stats)
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Response(ctx context.Context, direction Direction, r *WireResponse) context.Context {
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Done(ctx context.Context, err error) {
|
||||||
|
stats, ok := ctx.Value(statsKey).(*rpcStats)
|
||||||
|
if ok && stats != nil {
|
||||||
|
stats.end(ctx, &err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Read(ctx context.Context, bytes int64) context.Context {
|
||||||
|
telemetry.SentBytes.Record(ctx, bytes)
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Wrote(ctx context.Context, bytes int64) context.Context {
|
||||||
|
telemetry.ReceivedBytes.Record(ctx, bytes)
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *tracer) Error(ctx context.Context, err error) {
|
||||||
|
log.Printf("%v", err)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user