Skip to content

Commit 05568cd

Browse files
authored
feat: add apmplus callback handler to deer-go (#101)
* feat: add apmplus callback handler
1 parent fe522c0 commit 05568cd

File tree

5 files changed

+241
-15
lines changed

5 files changed

+241
-15
lines changed

flow/agent/deer-go/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ cp ./conf/deer-go.yaml.1 ./conf/deer-go.yaml
2424
./run.sh -s
2525
```
2626

27+
5. 如果想采集 trace 和 metrics 埋点信息,可通过配置 `APMPLUS_APP_KEY` 环境变量,来开启埋点采集。采集数据将上报至 APMPlus 。可在 [APMPlus 控制台](https://console.volcengine.com/apmplus-server) 中查看采集到的调用 trace 和 metrics 埋点信息。[火山引擎 APMPlus 文档](https://www.volcengine.com/docs/6431/69092)
28+
``` bash
29+
export APMPLUS_APP_KEY=your_app_key
30+
```
31+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2025 CloudWeGo Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package infra
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
24+
"github.com/RanFeng/ilog"
25+
"github.com/cloudwego/eino-ext/callbacks/apmplus"
26+
"github.com/cloudwego/eino/callbacks"
27+
hertzconfig "github.com/cloudwego/hertz/pkg/common/config"
28+
"github.com/hertz-contrib/obs-opentelemetry/provider"
29+
hertztracing "github.com/hertz-contrib/obs-opentelemetry/tracing"
30+
)
31+
32+
var EmptyHertzConfigOption = hertzconfig.Option{}
33+
34+
// InitAPMPlusTracing initializes APMPlus observability components for Eino applications
35+
// Creates Eino APMPlus callbacks and optionally initializes Hertz server tracing integration based on the withHertzServer flag.
36+
// Parameters:
37+
//
38+
// withHertzServer - If true, enables Hertz HTTP server tracing integration
39+
//
40+
// Returns:
41+
//
42+
// tracer - Hertz server configuration (nil if withHertzServer=false)
43+
// cfg - Tracing configuration instance (nil if withHertzServer=false)
44+
// shutdown - cleanup function for eino apmplus callback to flush telemetry data to APMPlus Server
45+
func InitAPMPlusTracing(ctx context.Context, withHertzServer bool) (tracer hertzconfig.Option, cfg *hertztracing.Config, shutdown func(ctx context.Context) error) {
46+
appKey := os.Getenv("APMPLUS_APP_KEY")
47+
if appKey == "" {
48+
return EmptyHertzConfigOption, nil, nil
49+
}
50+
region := os.Getenv("APMPLUS_REGION")
51+
if region == "" {
52+
region = "cn-beijing"
53+
}
54+
_, shutdown = initAPMPlusCallback(ctx, appKey, region)
55+
if !withHertzServer {
56+
return EmptyHertzConfigOption, nil, shutdown
57+
}
58+
// for hertz server, init hertz tracing integration
59+
tracer, cfg = initHertzTracing(ctx, appKey, region)
60+
return tracer, cfg, shutdown
61+
}
62+
63+
// initAPMPlusCallback initializes the Eino APMPlus callback handler.
64+
// It creates trace spans and collects metrics for Eino applications,
65+
// which will be sent to the APMPlus server for observability.
66+
func initAPMPlusCallback(ctx context.Context, appKey, region string) (callbacks.Handler, func(ctx context.Context) error) {
67+
ilog.EventInfo(ctx, "Init APMPlus callback, watch at: https://console.volcengine.com/apmplus-server", region)
68+
cbh, shutdown, err := apmplus.NewApmplusHandler(&apmplus.Config{
69+
Host: fmt.Sprintf("apmplus-%s.volces.com:4317", region),
70+
AppKey: appKey,
71+
ServiceName: "deer-go",
72+
Release: "release/v0.0.1",
73+
})
74+
if err != nil {
75+
ilog.EventError(ctx, err, "init apmplus callback failed")
76+
return nil, nil
77+
}
78+
callbacks.AppendGlobalHandlers(cbh)
79+
ilog.EventInfo(ctx, "Init APMPlus Callback success")
80+
return cbh, shutdown
81+
}
82+
83+
// initHertzTracing initializes Hertz framework tracing integration
84+
// It creates trace spans and collects metrics for incoming HTTP requests,
85+
// which will be sent to the APMPlus server for observability.
86+
func initHertzTracing(ctx context.Context, appKey, region string) (hertzconfig.Option, *hertztracing.Config) {
87+
ilog.EventInfo(ctx, "Init Hertz Tracing", region)
88+
_ = provider.NewOpenTelemetryProvider(
89+
provider.WithServiceName("deer-go"),
90+
provider.WithExportEndpoint(fmt.Sprintf("apmplus-%s.volces.com:4317", region)),
91+
provider.WithInsecure(),
92+
provider.WithHeaders(map[string]string{"X-ByteAPM-AppKey": appKey}),
93+
)
94+
tracer, cfg := hertztracing.NewServerTracer()
95+
return tracer, cfg
96+
97+
}

flow/agent/deer-go/go.mod

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ toolchain go1.23.7
66

77
require (
88
github.com/RanFeng/ilog v1.1.0
9-
github.com/cloudwego/eino v0.3.40
9+
github.com/cloudwego/eino v0.3.51
10+
github.com/cloudwego/eino-ext/callbacks/apmplus v0.0.1
1011
github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250514085234-473e80da5261
1112
github.com/cloudwego/eino-ext/components/tool/mcp v0.0.0-20250514085234-473e80da5261
1213
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250422092704-54e372e1fa3d
1314
github.com/cloudwego/hertz v0.10.0
1415
github.com/getkin/kin-openapi v0.118.0
1516
github.com/hertz-contrib/cors v0.1.0
17+
github.com/hertz-contrib/obs-opentelemetry/provider v0.3.0
18+
github.com/hertz-contrib/obs-opentelemetry/tracing v0.4.1
1619
github.com/mark3labs/mcp-go v0.20.0
1720
gopkg.in/yaml.v3 v3.0.1
1821
)
@@ -21,15 +24,21 @@ require (
2124
github.com/bytedance/gopkg v0.1.2 // indirect
2225
github.com/bytedance/sonic v1.13.3 // indirect
2326
github.com/bytedance/sonic/loader v0.3.0 // indirect
27+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
2428
github.com/cloudwego/base64x v0.1.5 // indirect
29+
github.com/cloudwego/eino-ext/libs/acl/opentelemetry v0.0.0-20250225080340-5935633151d3 // indirect
2530
github.com/cloudwego/gopkg v0.1.5 // indirect
2631
github.com/cloudwego/netpoll v0.7.1 // indirect
2732
github.com/dustin/go-humanize v1.0.1 // indirect
2833
github.com/evanphx/json-patch v0.5.2 // indirect
2934
github.com/fsnotify/fsnotify v1.9.0 // indirect
35+
github.com/go-logr/logr v1.4.2 // indirect
36+
github.com/go-logr/stdr v1.2.2 // indirect
3037
github.com/go-openapi/jsonpointer v0.21.1 // indirect
3138
github.com/go-openapi/swag v0.23.1 // indirect
39+
github.com/google/uuid v1.6.0 // indirect
3240
github.com/goph/emperror v0.17.2 // indirect
41+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
3342
github.com/invopop/yaml v0.1.0 // indirect
3443
github.com/josharian/intern v1.0.0 // indirect
3544
github.com/json-iterator/go v1.1.12 // indirect
@@ -46,7 +55,6 @@ require (
4655
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
4756
github.com/perimeterx/marshmallow v1.1.5 // indirect
4857
github.com/pkg/errors v0.9.1 // indirect
49-
github.com/rogpeppe/go-internal v1.9.0 // indirect
5058
github.com/rs/zerolog v1.34.0 // indirect
5159
github.com/sirupsen/logrus v1.9.3 // indirect
5260
github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect
@@ -56,9 +64,27 @@ require (
5664
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
5765
github.com/yargevad/filepathx v1.0.0 // indirect
5866
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
67+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
68+
go.opentelemetry.io/contrib/instrumentation/runtime v0.59.0 // indirect
69+
go.opentelemetry.io/contrib/propagators/b3 v1.20.0 // indirect
70+
go.opentelemetry.io/contrib/propagators/ot v1.20.0 // indirect
71+
go.opentelemetry.io/otel v1.34.0 // indirect
72+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect
73+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
74+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
75+
go.opentelemetry.io/otel/metric v1.34.0 // indirect
76+
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
77+
go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect
78+
go.opentelemetry.io/otel/trace v1.34.0 // indirect
79+
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
80+
go.uber.org/multierr v1.11.0 // indirect
5981
golang.org/x/arch v0.19.0 // indirect
6082
golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect
83+
golang.org/x/net v0.41.0 // indirect
6184
golang.org/x/sys v0.34.0 // indirect
6285
golang.org/x/text v0.27.0 // indirect
86+
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
87+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
88+
google.golang.org/grpc v1.69.4 // indirect
6389
google.golang.org/protobuf v1.36.6 // indirect
6490
)

0 commit comments

Comments
 (0)