-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
59fc768
commit 5061280
Showing
14 changed files
with
716 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package gomicro | ||
|
||
import ( | ||
"context" | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api" | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api/instrumenter" | ||
micro "go-micro.dev/v5" | ||
"go-micro.dev/v5/client" | ||
"go-micro.dev/v5/metadata" | ||
"go-micro.dev/v5/registry" | ||
"go-micro.dev/v5/selector" | ||
"go.opentelemetry.io/otel" | ||
"go.opentelemetry.io/otel/propagation" | ||
sdktrace "go.opentelemetry.io/otel/sdk/trace" | ||
semconv "go.opentelemetry.io/otel/semconv/v1.26.0" | ||
) | ||
|
||
var goMicroClientEnabler = instrumenter.NewDefaultInstrumentEnabler() | ||
|
||
type clientV5Wrapper struct { | ||
client.Client | ||
} | ||
|
||
func NewV5ClientWrapper(cli client.Client) client.Client { | ||
return &clientV5Wrapper{cli} | ||
} | ||
|
||
// Call is used for client calls | ||
func (s *clientV5Wrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { | ||
request := goMicroRequest{ | ||
request: req, | ||
reqType: CallRequest, | ||
ctx: ctx, | ||
} | ||
ctx = goMicroClientInstrument.Start(ctx, request) | ||
mda, _ := metadata.FromContext(request.ctx) | ||
md := metadata.Copy(mda) | ||
otel.GetTextMapPropagator().Inject(ctx, propagation.MapCarrier(md)) | ||
ctx = metadata.NewContext(ctx, md) | ||
request.ctx = ctx | ||
err := s.Client.Call(request.ctx, req, rsp, opts...) | ||
response := goMicroResponse{ | ||
response: rsp, | ||
err: err, | ||
ctx: request.ctx, | ||
} | ||
goMicroClientInstrument.End(ctx, request, response, err) | ||
return nil | ||
} | ||
|
||
func (s *clientV5Wrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { | ||
request := goMicroRequest{ | ||
request: req, | ||
reqType: StreamRequest, | ||
ctx: ctx, | ||
} | ||
ctx = goMicroClientInstrument.Start(ctx, request) | ||
stream, err := s.Client.Stream(ctx, req, opts...) | ||
response := goMicroResponse{ | ||
response: stream, | ||
err: err, | ||
ctx: ctx, | ||
} | ||
goMicroClientInstrument.End(ctx, request, response, err) | ||
|
||
return nil, nil | ||
|
||
} | ||
|
||
func (s *clientV5Wrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error { | ||
return s.Client.Publish(ctx, p, opts...) | ||
|
||
} | ||
|
||
func NewServiceOnEnter(call api.CallContext, opts ...micro.Option) { | ||
opts = append(opts, micro.WrapClient(NewV5ClientWrapper)) | ||
call.SetParam(0, opts) | ||
} | ||
|
||
func NextOnExit(call api.CallContext, nextSelector selector.Next, e error) { | ||
span := sdktrace.SpanFromGLS() | ||
if nextSelector != nil && span != nil { | ||
var selectWrapper selector.Next = func() (*registry.Node, error) { | ||
node, tmp := nextSelector() | ||
if node != nil { | ||
span.SetAttributes(semconv.ServerAddressKey.String(node.Address)) | ||
} | ||
return node, tmp | ||
} | ||
call.SetReturnVal(0, selectWrapper) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package gomicro | ||
|
||
import ( | ||
"context" | ||
"go-micro.dev/v5/client" | ||
"go-micro.dev/v5/server" | ||
"go.opentelemetry.io/otel/propagation" | ||
) | ||
|
||
var goMicroClientInstrument = BuildGoMicroClientInstrumenter() | ||
|
||
type requestType int | ||
|
||
const ( | ||
MessageRequest requestType = iota | ||
CallRequest | ||
StreamRequest | ||
) | ||
|
||
type goMicroRequest struct { | ||
reqType requestType | ||
request client.Request | ||
msg client.Message | ||
ctx context.Context | ||
propagators propagation.TextMapCarrier | ||
} | ||
|
||
type goMicroServerRequest struct { | ||
reqType requestType | ||
request server.Request | ||
msg server.Message | ||
ctx context.Context | ||
propagators propagation.TextMapCarrier | ||
} | ||
|
||
type goMicroResponse struct { | ||
response interface{} | ||
ctx context.Context | ||
err error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) 2024 Alibaba Group Holding Ltd. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package gomicro | ||
|
||
import ( | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api/instrumenter" | ||
) | ||
|
||
var goMicroEnabler = instrumenter.NewDefaultInstrumentEnabler() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// Copyright (c) 2024 Alibaba Group Holding Ltd. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package gomicro | ||
|
||
import ( | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api-semconv/instrumenter/http" | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api-semconv/instrumenter/net" | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api/instrumenter" | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api/utils" | ||
"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/inst-api/version" | ||
"go-micro.dev/v5/metadata" | ||
"go.opentelemetry.io/otel" | ||
"go.opentelemetry.io/otel/propagation" | ||
"go.opentelemetry.io/otel/sdk/instrumentation" | ||
) | ||
|
||
type GoMicroServerAttrsGetter struct { | ||
} | ||
|
||
func (n GoMicroServerAttrsGetter) GetRequestMethod(request goMicroServerRequest) string { | ||
return request.request.Method() | ||
} | ||
func (n GoMicroServerAttrsGetter) GetHttpRequestHeader(request goMicroServerRequest, name string) []string { | ||
all := make([]string, 0) | ||
md, ok := metadata.FromContext(request.ctx) | ||
if ok { | ||
value, ok := md.Get(name) | ||
if ok { | ||
all = append(all, string(value)) | ||
} | ||
} | ||
return all | ||
} | ||
func (n GoMicroServerAttrsGetter) GetHttpResponseStatusCode(request goMicroServerRequest, response goMicroResponse, err error) int { | ||
if err != nil { | ||
return 500 | ||
} | ||
return 200 | ||
} | ||
func (n GoMicroServerAttrsGetter) GetHttpResponseHeader(request goMicroServerRequest, response goMicroResponse, name string) []string { | ||
all := make([]string, 0) | ||
md, ok := metadata.FromContext(response.ctx) | ||
if ok { | ||
value, ok := md.Get(name) | ||
if ok { | ||
all = append(all, string(value)) | ||
} | ||
} | ||
return all | ||
} | ||
func (n GoMicroServerAttrsGetter) GetErrorType(request goMicroServerRequest, response goMicroResponse, err error) string { | ||
return "" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetUrlScheme(request goMicroServerRequest) string { | ||
return "http" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetUrlPath(request goMicroServerRequest) string { | ||
return request.request.Endpoint() | ||
} | ||
func (n GoMicroServerAttrsGetter) GetUrlQuery(request goMicroServerRequest) string { | ||
return "" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkType(request goMicroServerRequest, response goMicroResponse) string { | ||
return "ipv4" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkTransport(request goMicroServerRequest, response goMicroResponse) string { | ||
return "tcp" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkProtocolName(request goMicroServerRequest, response goMicroResponse) string { | ||
return "http" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkProtocolVersion(request goMicroServerRequest, response goMicroResponse) string { | ||
return "" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkLocalInetAddress(request goMicroServerRequest, response goMicroResponse) string { | ||
return "" | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkLocalPort(request goMicroServerRequest, response goMicroResponse) int { | ||
return 0 | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkPeerInetAddress(request goMicroServerRequest, response goMicroResponse) string { | ||
return request.request.Service() | ||
} | ||
func (n GoMicroServerAttrsGetter) GetNetworkPeerPort(request goMicroServerRequest, response goMicroResponse) int { | ||
return 0 | ||
} | ||
func (n GoMicroServerAttrsGetter) GetHttpRoute(request goMicroServerRequest) string { | ||
return request.request.Endpoint() | ||
} | ||
|
||
type goMicroServerTextMapCarrier struct { | ||
request *goMicroServerRequest | ||
} | ||
|
||
func (h goMicroServerTextMapCarrier) Get(key string) string { | ||
mda, _ := metadata.FromContext(h.request.ctx) | ||
md := metadata.Copy(mda) | ||
value, _ := md.Get(key) | ||
return value | ||
} | ||
|
||
func (h goMicroServerTextMapCarrier) Set(key string, value string) { | ||
mda, _ := metadata.FromContext(h.request.ctx) | ||
md := metadata.Copy(mda) | ||
md.Set(key, value) | ||
h.request.ctx = metadata.NewContext(h.request.ctx, md) | ||
} | ||
|
||
func (h goMicroServerTextMapCarrier) Keys() []string { | ||
keys := make([]string, 0) | ||
mda, _ := metadata.FromContext(h.request.ctx) | ||
md := metadata.Copy(mda) | ||
for k, _ := range md { | ||
keys = append(keys, k) | ||
} | ||
return keys | ||
} | ||
|
||
func BuildGoMicroServerOtelInstrumenter() *instrumenter.PropagatingFromUpstreamInstrumenter[goMicroServerRequest, goMicroResponse] { | ||
builder := instrumenter.Builder[goMicroServerRequest, goMicroResponse]{} | ||
serverGetter := GoMicroServerAttrsGetter{} | ||
commonExtractor := http.HttpCommonAttrsExtractor[goMicroServerRequest, goMicroResponse, GoMicroServerAttrsGetter, GoMicroServerAttrsGetter]{HttpGetter: serverGetter, NetGetter: serverGetter} | ||
networkExtractor := net.NetworkAttrsExtractor[goMicroServerRequest, goMicroResponse, GoMicroServerAttrsGetter]{Getter: serverGetter} | ||
urlExtractor := net.UrlAttrsExtractor[goMicroServerRequest, goMicroResponse, GoMicroServerAttrsGetter]{Getter: serverGetter} | ||
return builder.Init().SetSpanStatusExtractor(http.HttpServerSpanStatusExtractor[goMicroServerRequest, goMicroResponse]{Getter: serverGetter}).SetSpanNameExtractor(&http.HttpServerSpanNameExtractor[goMicroServerRequest, goMicroResponse]{Getter: serverGetter}). | ||
SetSpanKindExtractor(&instrumenter.AlwaysServerExtractor[goMicroServerRequest]{}). | ||
AddOperationListeners(http.HttpServerMetrics("gomicro.server")). | ||
SetInstrumentationScope(instrumentation.Scope{ | ||
Name: utils.GOMICRO_SERVER_SCOPE_NAME, | ||
Version: version.Tag, | ||
}). | ||
AddAttributesExtractor(&http.HttpServerAttrsExtractor[goMicroServerRequest, goMicroResponse, GoMicroServerAttrsGetter, GoMicroServerAttrsGetter, GoMicroServerAttrsGetter]{Base: commonExtractor, NetworkExtractor: networkExtractor, UrlExtractor: urlExtractor}).BuildPropagatingFromUpstreamInstrumenter(func(n goMicroServerRequest) propagation.TextMapCarrier { | ||
return goMicroServerTextMapCarrier{request: &n} | ||
}, otel.GetTextMapPropagator()) | ||
} |
Oops, something went wrong.