mirror of
https://gitee.com/johng/gf.git
synced 2024-11-29 18:57:44 +08:00
enable OpenTelemetry in default for some core components
This commit is contained in:
parent
000483cc6f
commit
aee52fd56e
@ -38,7 +38,7 @@ const (
|
|||||||
|
|
||||||
// addSqlToTracing adds sql information to tracer if it's enabled.
|
// addSqlToTracing adds sql information to tracer if it's enabled.
|
||||||
func (c *Core) addSqlToTracing(ctx context.Context, sql *Sql) {
|
func (c *Core) addSqlToTracing(ctx context.Context, sql *Sql) {
|
||||||
if !gtrace.IsTracingInternal() || !gtrace.IsActivated(ctx) {
|
if gtrace.IsUsingDefaultProvider() || !gtrace.IsTracingInternal() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tr := otel.GetTracerProvider().Tracer(
|
tr := otel.GetTracerProvider().Tracer(
|
||||||
|
@ -40,7 +40,7 @@ const (
|
|||||||
|
|
||||||
// addTracingItem checks and adds redis tracing information to OpenTelemetry.
|
// addTracingItem checks and adds redis tracing information to OpenTelemetry.
|
||||||
func (c *RedisConn) addTracingItem(ctx context.Context, item *tracingItem) {
|
func (c *RedisConn) addTracingItem(ctx context.Context, item *tracingItem) {
|
||||||
if !gtrace.IsTracingInternal() || !gtrace.IsActivated(ctx) {
|
if gtrace.IsUsingDefaultProvider() || !gtrace.IsTracingInternal() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tr := otel.GetTracerProvider().Tracer(
|
tr := otel.GetTracerProvider().Tracer(
|
||||||
|
5
go.mod
5
go.mod
@ -12,8 +12,9 @@ require (
|
|||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/grokify/html-strip-tags-go v0.0.1
|
github.com/grokify/html-strip-tags-go v0.0.1
|
||||||
github.com/olekukonko/tablewriter v0.0.5
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
go.opentelemetry.io/otel v1.2.0
|
go.opentelemetry.io/otel v1.3.0
|
||||||
go.opentelemetry.io/otel/trace v1.2.0
|
go.opentelemetry.io/otel/sdk v1.3.0
|
||||||
|
go.opentelemetry.io/otel/trace v1.3.0
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
||||||
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2
|
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
|
16
go.sum
16
go.sum
@ -15,6 +15,11 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
|||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||||
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.2.1 h1:DX7uPQ4WgAWfoh+NGGlbJQswnYIVvz0SRlLS3rPZQDA=
|
||||||
|
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/stdr v1.2.0 h1:j4LrlVXgrbIWO83mmQUnK0Hi+YnbD+vzrE1z/EphbFE=
|
||||||
|
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
|
||||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
||||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
@ -69,10 +74,12 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
|||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ=
|
go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
|
||||||
go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I=
|
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
|
||||||
go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0=
|
go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJreAI=
|
||||||
go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0=
|
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
|
||||||
|
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
|
||||||
|
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@ -104,6 +111,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
56
internal/tracing/tracing.go
Normal file
56
internal/tracing/tracing.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the MIT License.
|
||||||
|
// If a copy of the MIT was not distributed with this file,
|
||||||
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
|
||||||
|
// Package tracing provides some utility functions for tracing functionality.
|
||||||
|
package tracing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/container/gtype"
|
||||||
|
"github.com/gogf/gf/v2/encoding/gbinary"
|
||||||
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
randomInitSequence = int32(grand.Intn(math.MaxInt32))
|
||||||
|
sequence = gtype.NewInt32(randomInitSequence)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewIDs creates and returns a new trace and span ID.
|
||||||
|
func NewIDs() (traceID trace.TraceID, spanID trace.SpanID) {
|
||||||
|
var (
|
||||||
|
timestampNanoBytes = gbinary.EncodeInt64(time.Now().UnixNano())
|
||||||
|
sequenceBytes = gbinary.EncodeInt32(sequence.Add(1))
|
||||||
|
randomBytes = grand.B(4)
|
||||||
|
)
|
||||||
|
copy(traceID[:], timestampNanoBytes)
|
||||||
|
copy(traceID[8:], sequenceBytes)
|
||||||
|
copy(traceID[12:], randomBytes)
|
||||||
|
copy(spanID[:], timestampNanoBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTraceID creates and returns a trace ID.
|
||||||
|
func NewTraceID() (traceID trace.TraceID) {
|
||||||
|
var (
|
||||||
|
timestampNanoBytes = gbinary.EncodeInt64(time.Now().UnixNano())
|
||||||
|
sequenceBytes = gbinary.EncodeInt32(sequence.Add(1))
|
||||||
|
randomBytes = grand.B(4)
|
||||||
|
)
|
||||||
|
copy(traceID[:], timestampNanoBytes)
|
||||||
|
copy(traceID[8:], sequenceBytes)
|
||||||
|
copy(traceID[12:], randomBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSpanID creates and returns a span ID.
|
||||||
|
func NewSpanID() (spanID trace.SpanID) {
|
||||||
|
copy(spanID[:], gbinary.EncodeInt64(time.Now().UnixNano()))
|
||||||
|
return
|
||||||
|
}
|
@ -20,7 +20,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/net/gtrace"
|
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2"
|
"github.com/gogf/gf/v2"
|
||||||
@ -65,10 +64,8 @@ func New() *Client {
|
|||||||
cookies: make(map[string]string),
|
cookies: make(map[string]string),
|
||||||
}
|
}
|
||||||
c.header["User-Agent"] = defaultClientAgent
|
c.header["User-Agent"] = defaultClientAgent
|
||||||
// It enables OpenTelemetry for client if tracing feature is enabled.
|
// It enables OpenTelemetry for client in default.
|
||||||
if gtrace.IsEnabled() {
|
c.Use(internalMiddlewareTracing)
|
||||||
c.Use(MiddlewareTracing)
|
|
||||||
}
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ const (
|
|||||||
tracingMiddlewareHandled gctx.StrKey = `MiddlewareClientTracingHandled`
|
tracingMiddlewareHandled gctx.StrKey = `MiddlewareClientTracingHandled`
|
||||||
)
|
)
|
||||||
|
|
||||||
// MiddlewareTracing is a client middleware that enables tracing feature using standards of OpenTelemetry.
|
// internalMiddlewareTracing is a client middleware that enables tracing feature using standards of OpenTelemetry.
|
||||||
func MiddlewareTracing(c *Client, r *http.Request) (response *Response, err error) {
|
func internalMiddlewareTracing(c *Client, r *http.Request) (response *Response, err error) {
|
||||||
var (
|
var (
|
||||||
ctx = r.Context()
|
ctx = r.Context()
|
||||||
)
|
)
|
||||||
@ -70,6 +70,12 @@ func MiddlewareTracing(c *Client, r *http.Request) (response *Response, err erro
|
|||||||
// Inject tracing content into http header.
|
// Inject tracing content into http header.
|
||||||
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(r.Header))
|
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(r.Header))
|
||||||
|
|
||||||
|
// If it is now using default trace provider, ot then does no complex tracing jobs.
|
||||||
|
if gtrace.IsUsingDefaultProvider() {
|
||||||
|
response, err = c.Next(r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Continue client handler executing.
|
// Continue client handler executing.
|
||||||
response, err = c.Next(
|
response, err = c.Next(
|
||||||
r.WithContext(
|
r.WithContext(
|
||||||
|
@ -38,8 +38,8 @@ const (
|
|||||||
tracingMiddlewareHandled gctx.StrKey = `MiddlewareServerTracingHandled`
|
tracingMiddlewareHandled gctx.StrKey = `MiddlewareServerTracingHandled`
|
||||||
)
|
)
|
||||||
|
|
||||||
// MiddlewareServerTracing is a serer middleware that enables tracing feature using standards of OpenTelemetry.
|
// internalMiddlewareServerTracing is a serer middleware that enables tracing feature using standards of OpenTelemetry.
|
||||||
func MiddlewareServerTracing(r *Request) {
|
func internalMiddlewareServerTracing(r *Request) {
|
||||||
var (
|
var (
|
||||||
ctx = r.Context()
|
ctx = r.Context()
|
||||||
)
|
)
|
||||||
@ -73,6 +73,12 @@ func MiddlewareServerTracing(r *Request) {
|
|||||||
// Inject tracing context.
|
// Inject tracing context.
|
||||||
r.SetCtx(ctx)
|
r.SetCtx(ctx)
|
||||||
|
|
||||||
|
// If it is now using default trace provider, ot then does no complex tracing jobs.
|
||||||
|
if gtrace.IsUsingDefaultProvider() {
|
||||||
|
r.Middleware.Next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Request content logging.
|
// Request content logging.
|
||||||
reqBodyContentBytes, _ := ioutil.ReadAll(r.Body)
|
reqBodyContentBytes, _ := ioutil.ReadAll(r.Body)
|
||||||
r.Body = utils.NewReadCloser(reqBodyContentBytes, false)
|
r.Body = utils.NewReadCloser(reqBodyContentBytes, false)
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/net/gtrace"
|
|
||||||
"github.com/olekukonko/tablewriter"
|
"github.com/olekukonko/tablewriter"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/container/garray"
|
"github.com/gogf/gf/v2/container/garray"
|
||||||
@ -116,10 +115,8 @@ func GetServer(name ...interface{}) *Server {
|
|||||||
}
|
}
|
||||||
// Record the server to internal server mapping by name.
|
// Record the server to internal server mapping by name.
|
||||||
serverMapping.Set(serverName, s)
|
serverMapping.Set(serverName, s)
|
||||||
// It enables OpenTelemetry for server if tracing feature is enabled.
|
// It enables OpenTelemetry for server in default.
|
||||||
if gtrace.IsEnabled() {
|
s.Use(internalMiddlewareServerTracing)
|
||||||
s.Use(MiddlewareServerTracing)
|
|
||||||
}
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/internal/intlog"
|
"github.com/gogf/gf/v2/net/gtrace/internal/provider"
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/propagation"
|
"go.opentelemetry.io/otel/propagation"
|
||||||
@ -38,7 +38,6 @@ var (
|
|||||||
intranetIps, _ = gipv4.GetIntranetIpArray()
|
intranetIps, _ = gipv4.GetIntranetIpArray()
|
||||||
intranetIpStr = strings.Join(intranetIps, ",")
|
intranetIpStr = strings.Join(intranetIps, ",")
|
||||||
hostname, _ = os.Hostname()
|
hostname, _ = os.Hostname()
|
||||||
traceEnabled = false // traceEnabled enables tracing feature for all.
|
|
||||||
tracingInternal = true // tracingInternal enables tracing for internal type spans.
|
tracingInternal = true // tracingInternal enables tracing for internal type spans.
|
||||||
tracingMaxContentLogSize = 512 * 1024 // Max log size for request and response body, especially for HTTP/RPC request.
|
tracingMaxContentLogSize = 512 * 1024 // Max log size for request and response body, especially for HTTP/RPC request.
|
||||||
// defaultTextMapPropagator is the default propagator for context propagation between peers.
|
// defaultTextMapPropagator is the default propagator for context propagation between peers.
|
||||||
@ -49,29 +48,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
traceEnabled = gconv.Bool(command.GetOptWithEnv(commandEnvKeyForTraceEnabled, "false"))
|
|
||||||
tracingInternal = gconv.Bool(command.GetOptWithEnv(commandEnvKeyForTracingInternal, "true"))
|
tracingInternal = gconv.Bool(command.GetOptWithEnv(commandEnvKeyForTracingInternal, "true"))
|
||||||
if maxContentLogSize := gconv.Int(command.GetOptWithEnv(commandEnvKeyForMaxContentLogSize)); maxContentLogSize > 0 {
|
if maxContentLogSize := gconv.Int(command.GetOptWithEnv(commandEnvKeyForMaxContentLogSize)); maxContentLogSize > 0 {
|
||||||
tracingMaxContentLogSize = maxContentLogSize
|
tracingMaxContentLogSize = maxContentLogSize
|
||||||
}
|
}
|
||||||
|
// Default trace provider.
|
||||||
|
otel.SetTracerProvider(provider.New())
|
||||||
CheckSetDefaultTextMapPropagator()
|
CheckSetDefaultTextMapPropagator()
|
||||||
intlog.Printf(context.TODO(), `traceEnabled initialized as: %v`, traceEnabled)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEnabled enables or disables the tracing feature.
|
// IsUsingDefaultProvider checks and return if currently using default trace provider.
|
||||||
func SetEnabled(enabled bool) {
|
func IsUsingDefaultProvider() bool {
|
||||||
traceEnabled = enabled
|
_, ok := otel.GetTracerProvider().(*provider.TracerProvider)
|
||||||
intlog.Printf(context.TODO(), `traceEnabled SetEnabled: %v`, enabled)
|
return ok
|
||||||
}
|
|
||||||
|
|
||||||
// IsEnabled checks and returns if tracing feature is configured enabled.
|
|
||||||
func IsEnabled() bool {
|
|
||||||
return traceEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsActivated checks given context and returns if tracing feature is actually activated in this context.
|
|
||||||
func IsActivated(ctx context.Context) bool {
|
|
||||||
return GetTraceID(ctx) != ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTracingInternal returns whether tracing spans of internal components.
|
// IsTracingInternal returns whether tracing spans of internal components.
|
||||||
|
@ -52,15 +52,17 @@ func TestNewCarrier(t *testing.T) {
|
|||||||
SpanID: spanID,
|
SpanID: spanID,
|
||||||
TraceFlags: trace.FlagsSampled,
|
TraceFlags: trace.FlagsSampled,
|
||||||
}))
|
}))
|
||||||
|
sc := trace.SpanContextFromContext(ctx)
|
||||||
|
t.Assert(sc.TraceID().String(), traceID.String())
|
||||||
|
t.Assert(sc.SpanID().String(), "00f067aa0ba902b7")
|
||||||
|
|
||||||
ctx, _ = otel.Tracer("").Start(ctx, "inject")
|
ctx, _ = otel.Tracer("").Start(ctx, "inject")
|
||||||
carrier1 := gtrace.NewCarrier()
|
carrier1 := gtrace.NewCarrier()
|
||||||
otel.GetTextMapPropagator().Inject(ctx, carrier1)
|
otel.GetTextMapPropagator().Inject(ctx, carrier1)
|
||||||
t.Assert(carrier1.String(), `{"traceparent":"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"}`)
|
|
||||||
|
|
||||||
ctx = otel.GetTextMapPropagator().Extract(ctx, carrier1)
|
ctx = otel.GetTextMapPropagator().Extract(ctx, carrier1)
|
||||||
gotSc := trace.SpanContextFromContext(ctx)
|
gotSc := trace.SpanContextFromContext(ctx)
|
||||||
t.Assert(gotSc.TraceID().String(), traceID.String())
|
t.Assert(gotSc.TraceID().String(), traceID.String())
|
||||||
t.Assert(gotSc.SpanID().String(), "00f067aa0ba902b7")
|
// New span is created internally, so the SpanID is different.
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
46
net/gtrace/gtrace_z_unit_feature_http_test.go
Normal file
46
net/gtrace/gtrace_z_unit_feature_http_test.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the MIT License.
|
||||||
|
// If a copy of the MIT was not distributed with this file,
|
||||||
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
|
||||||
|
package gtrace_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
|
"github.com/gogf/gf/v2/net/gtrace"
|
||||||
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
|
"github.com/gogf/gf/v2/test/gtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Client_Server_Tracing(t *testing.T) {
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
p := 8888
|
||||||
|
s := g.Server(p)
|
||||||
|
s.BindHandler("/", func(r *ghttp.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
g.Log().Print(ctx, "GetTraceID:", gtrace.GetTraceID(ctx))
|
||||||
|
r.Response.Write(gtrace.GetTraceID(ctx))
|
||||||
|
})
|
||||||
|
s.SetPort(p)
|
||||||
|
s.SetDumpRouterMap(false)
|
||||||
|
t.AssertNil(s.Start())
|
||||||
|
defer s.Shutdown()
|
||||||
|
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
ctx := gctx.New()
|
||||||
|
|
||||||
|
prefix := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||||
|
client := g.Client()
|
||||||
|
client.SetPrefix(prefix)
|
||||||
|
t.Assert(gtrace.IsUsingDefaultProvider(), true)
|
||||||
|
t.Assert(client.GetContent(ctx, "/"), gtrace.GetTraceID(ctx))
|
||||||
|
t.Assert(client.GetContent(ctx, "/"), gctx.CtxId(ctx))
|
||||||
|
})
|
||||||
|
}
|
23
net/gtrace/internal/provider/provider.go
Normal file
23
net/gtrace/internal/provider/provider.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the MIT License.
|
||||||
|
// If a copy of the MIT was not distributed with this file,
|
||||||
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TracerProvider struct {
|
||||||
|
*sdkTrace.TracerProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *TracerProvider {
|
||||||
|
return &TracerProvider{
|
||||||
|
TracerProvider: sdkTrace.NewTracerProvider(
|
||||||
|
sdkTrace.WithIDGenerator(NewIDGenerator()),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
30
net/gtrace/internal/provider/provider_idgenerator.go
Normal file
30
net/gtrace/internal/provider/provider_idgenerator.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the MIT License.
|
||||||
|
// If a copy of the MIT was not distributed with this file,
|
||||||
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/internal/tracing"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IDGenerator struct{}
|
||||||
|
|
||||||
|
func NewIDGenerator() *IDGenerator {
|
||||||
|
return &IDGenerator{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewIDs creates and returns a new trace and span ID.
|
||||||
|
func (id *IDGenerator) NewIDs(ctx context.Context) (traceID trace.TraceID, spanID trace.SpanID) {
|
||||||
|
return tracing.NewIDs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSpanID returns an ID for a new span in the trace with traceID.
|
||||||
|
func (id *IDGenerator) NewSpanID(ctx context.Context, traceID trace.TraceID) (spanID trace.SpanID) {
|
||||||
|
return tracing.NewSpanID()
|
||||||
|
}
|
@ -10,7 +10,7 @@ package gctx
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/guid"
|
"github.com/gogf/gf/v2/net/gtrace"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -18,12 +18,6 @@ type (
|
|||||||
StrKey string // StrKey is a type for warps basic type string as context key.
|
StrKey string // StrKey is a type for warps basic type string as context key.
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// CtxKey is custom tracing context key for context id.
|
|
||||||
// The context id a unique string for certain context.
|
|
||||||
CtxKey StrKey = "GoFrameCtxId"
|
|
||||||
)
|
|
||||||
|
|
||||||
// New creates and returns a context which contains context id.
|
// New creates and returns a context which contains context id.
|
||||||
func New() context.Context {
|
func New() context.Context {
|
||||||
return WithCtx(context.Background())
|
return WithCtx(context.Background())
|
||||||
@ -31,31 +25,12 @@ func New() context.Context {
|
|||||||
|
|
||||||
// WithCtx creates and returns a context containing context id upon given parent context `ctx`.
|
// WithCtx creates and returns a context containing context id upon given parent context `ctx`.
|
||||||
func WithCtx(ctx context.Context) context.Context {
|
func WithCtx(ctx context.Context) context.Context {
|
||||||
return WithPrefix(ctx, "")
|
ctx, span := gtrace.NewSpan(ctx, "gctx.WithCtx")
|
||||||
}
|
defer span.End()
|
||||||
|
return ctx
|
||||||
// WithPrefix creates and returns a context containing context id upon given parent context `ctx`.
|
|
||||||
// The generated context id has custom prefix string specified by parameter `prefix`.
|
|
||||||
func WithPrefix(ctx context.Context, prefix string) context.Context {
|
|
||||||
return WithCtxId(ctx, prefix+getUniqueID())
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCtxId creates and returns a context containing context id upon given parent context `ctx`.
|
|
||||||
// The generated context id value is specified by parameter `id`.
|
|
||||||
func WithCtxId(ctx context.Context, id string) context.Context {
|
|
||||||
if id == "" {
|
|
||||||
return New()
|
|
||||||
}
|
|
||||||
return context.WithValue(ctx, CtxKey, id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CtxId retrieves and returns the context id from context.
|
// CtxId retrieves and returns the context id from context.
|
||||||
func CtxId(ctx context.Context) string {
|
func CtxId(ctx context.Context) string {
|
||||||
s, _ := ctx.Value(CtxKey).(string)
|
return gtrace.GetTraceID(ctx)
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// getUniqueID produces a global unique string.
|
|
||||||
func getUniqueID() string {
|
|
||||||
return guid.S()
|
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,13 @@ import (
|
|||||||
|
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
"github.com/gogf/gf/v2/test/gtest"
|
"github.com/gogf/gf/v2/test/gtest"
|
||||||
"github.com/gogf/gf/v2/text/gstr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_New(t *testing.T) {
|
func Test_New(t *testing.T) {
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
ctx := gctx.New()
|
ctx := gctx.New()
|
||||||
t.AssertNE(ctx, nil)
|
t.AssertNE(ctx, nil)
|
||||||
t.AssertNE(gctx.CtxId(ctx), "")
|
t.Assert(gctx.CtxId(ctx), "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,25 +26,7 @@ func Test_WithCtx(t *testing.T) {
|
|||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
ctx := context.WithValue(context.TODO(), "TEST", 1)
|
ctx := context.WithValue(context.TODO(), "TEST", 1)
|
||||||
ctx = gctx.WithCtx(ctx)
|
ctx = gctx.WithCtx(ctx)
|
||||||
t.AssertNE(gctx.CtxId(ctx), "")
|
t.Assert(gctx.CtxId(ctx), "")
|
||||||
t.Assert(ctx.Value("TEST"), 1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_WithPrefix(t *testing.T) {
|
|
||||||
gtest.C(t, func(t *gtest.T) {
|
|
||||||
ctx := context.WithValue(context.TODO(), "TEST", 1)
|
|
||||||
ctx = gctx.WithPrefix(ctx, "H-")
|
|
||||||
t.Assert(gstr.Contains(gctx.CtxId(ctx), "H-"), true)
|
|
||||||
t.Assert(ctx.Value("TEST"), 1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_WithValue(t *testing.T) {
|
|
||||||
gtest.C(t, func(t *gtest.T) {
|
|
||||||
ctx := context.WithValue(context.TODO(), "TEST", 1)
|
|
||||||
ctx = gctx.WithCtxId(ctx, "123")
|
|
||||||
t.Assert(gctx.CtxId(ctx), "123")
|
|
||||||
t.Assert(ctx.Value("TEST"), 1)
|
t.Assert(ctx.Value("TEST"), 1)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
"github.com/gogf/gf/v2/errors/gcode"
|
"github.com/gogf/gf/v2/errors/gcode"
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
"github.com/gogf/gf/v2/internal/intlog"
|
"github.com/gogf/gf/v2/internal/intlog"
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
"github.com/gogf/gf/v2/os/gfile"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
"github.com/gogf/gf/v2/util/gutil"
|
"github.com/gogf/gf/v2/util/gutil"
|
||||||
@ -52,7 +51,7 @@ func DefaultConfig() Config {
|
|||||||
File: defaultFileFormat,
|
File: defaultFileFormat,
|
||||||
Flags: F_TIME_STD,
|
Flags: F_TIME_STD,
|
||||||
Level: LEVEL_ALL,
|
Level: LEVEL_ALL,
|
||||||
CtxKeys: []interface{}{gctx.CtxKey},
|
CtxKeys: []interface{}{},
|
||||||
StStatus: 1,
|
StStatus: 1,
|
||||||
HeaderPrint: true,
|
HeaderPrint: true,
|
||||||
StdoutPrint: true,
|
StdoutPrint: true,
|
||||||
@ -167,7 +166,6 @@ func (l *Logger) SetStackFilter(filter string) {
|
|||||||
// Note that multiple calls of this function will overwrite the previous set context keys.
|
// Note that multiple calls of this function will overwrite the previous set context keys.
|
||||||
func (l *Logger) SetCtxKeys(keys ...interface{}) {
|
func (l *Logger) SetCtxKeys(keys ...interface{}) {
|
||||||
l.config.CtxKeys = keys
|
l.config.CtxKeys = keys
|
||||||
l.config.CtxKeys = append(l.config.CtxKeys, gctx.CtxKey)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendCtxKeys appends extra keys to logger.
|
// AppendCtxKeys appends extra keys to logger.
|
||||||
|
Loading…
Reference in New Issue
Block a user