tencent cloud

All product documents
Tencent Cloud Observability Platform
Access of Go Applications via eBPF Agents
Last updated: 2025-03-04 22:02:22
Access of Go Applications via eBPF Agents
Last updated: 2025-03-04 22:02:22
Notes:
OpenTelemetry is a collection of tools, APIs, and SDKs for monitoring, generating, collecting, and exporting telemetry data (metrics, logs, and traces) to help users analyze the performance and behaviors of the software. For more information about OpenTelemetry, see the OpenTelemetry Official Website.
eBPF (Extended Berkeley Packet Filter) allows safe execution of user-defined code in kernel space without the need to modify kernel source code or load kernel modules. Combined with OpenTelemetry, eBPF enables users to achieve comprehensive monitoring capabilities without manually instrumenting code.
The Tencent Cloud eBPF agent a secondary development based on open-source community project opentelemetry-go-instrumentation, and its features are still rapidly evolving.
This document describes how to achieve access of Go applications via the Tencent Cloud eBPF agent.

Prerequisites

Note:
Currently, eBPF only supports Linux, with kernel version 4.19 or later.
System macOS and Windows (including Linux containers running on such hosts) are not supported at this time.
The Go version should be 1.18 or later. The following libraries and frameworks are supported:
Library/Framework
Version
database/sql
go1.12 to go1.23.0
github.com/segmentio/kafka-go
v0.4.1 to v0.4.47
google.golang.org/grpc
v1.14.0 to v1.66.0
net/http
go1.12 to go1.22.6
Note:
The Web frameworks based on net/http, such as Gin, are supported.

Access Process

Step 1. Getting the Access Point and Token

1. Log in to the TCOP console.
2. In the left sidebar, select Application Performance Management, and then click Application List > Access application.
3. On the page that pops up on the right, select the Go language.
4. On the Access Go Application page, select the Region and Business System.
5. Select OpenTelemetry as Access protocol type.
6. Select a Reporting method through which you want to report data, and obtain your Access Point and Token.
Note:
Report over private network: This reporting method requires your service to run in the Tencent Cloud VPC. The direct connection through VPC can help avoid the security risks of public network communication and save costs on reporting traffic.
Report over public network: If your service is deployed locally or in non-Tencent Cloud VPC, you can report data in this method. However, it involves security risks in public network communication and incurs reporting traffic fees.

Step 2: Downloading the Agent

linux/amd64 agent Download.
linux/arm64 agent Download.
Grant the execution permission to the agent:
chmod +x otel-go-instrumentation

Step 3: Installing the Agent

1. Confirm the execution path of the application.

Compile the applications into a binary file and confirm the full path when the application starts.

2. Run the agent.

Running the agent requires the system root permission. Use the following command to achieve access:
sudo OTEL_GO_AUTO_TARGET_EXE=</path/to/executable_binary> \
OTEL_SERVICE_NAME=<serviceName> \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_TRACES_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint> \
OTEL_RESOURCE_ATTRIBUTES=token=<token>,host.name=<hostName> \
./otel-go-instrumentation
The corresponding field descriptions are as follows:
</path/to/executable_binary> : The path of the application executable file. It must be an absolute path here.
<serviceName>: The application name. Multiple application processes that use the same serviceName to access will appear as multiple instances under the same application in Application Performance Management (APM). The application name can contain up to 63 characters consisting of lowercase letters, digits, and the hyphen (-) only. It must start with a lowercase letter and end with a digit or lowercase letter.
<endpoint>: The access point obtained in the previous step. Note that you must add the http:// prefix here.
<token>: The business system token obtained in the previous step.
<hostName>: The hostname of this instance, which is the unique identifier of the application instance. It can usually be set to the IP address of the application instance.
The following example uses myService as the application name, /root as the execution path, myToken as the business system token, 192.168.0.10 as the hostname, and http://ap-guangzhou.apm.tencentcs.com:4317 as the access point. The complete startup command is:
sudo OTEL_GO_AUTO_TARGET_EXE=/root/myService \
OTEL_SERVICE_NAME=myService \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_TRACES_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_ENDPOINT=http://ap-guangzhou.apm.tencentcs.com:4317 \
OTEL_RESOURCE_ATTRIBUTES=token=myToken,host.name=192.168.0.10 \
./otel-go-instrumentation
To learn more about access methods, see official documentation.

3. Run the application.

Run the application. When an API call occurs, the agent outputs logs. If the application stops running, the agent does not need to be stopped. Automatic instrumentation will occur when the application starts again.

4. Access Verification

Access side.
The log output of the agent contains the instrumentation loaded successfully field, indicating successful access.
{"level":"info","ts":1725609047.2234442,"logger":"go.opentelemetry.io/auto","caller":"cli/main.go:119","msg":"starting instrumentation..."}
{"level":"info","ts":1725609047.2235398,"logger":"Instrumentation.Manager","caller":"instrumentation/manager.go:195","msg":"loading probe","name":"net/http/server"}
{"level":"info","ts":1725609047.388379,"logger":"go.opentelemetry.io/auto","caller":"cli/main.go:115","msg":"instrumentation loaded successfully"}
APM console.
When an API call occurs, the application will be displayed in APM > Application List. Click Application Name/ID to enter the application details page, and then select Instance monitoring to view the application instance. Since there is certain delay in processing of observable data, you may wait for about 30 seconds if the application or instance is not found in the console.

Troubleshooting Access Errors

The agent produces only one log output:
{"level":"info","ts":1725609014.2038825,"logger":"go.opentelemetry.io/auto","caller":"cli/main.go:86","msg":"building OpenTelemetry Go instrumentation ...","globalImpl":false}
This generally occurs in the following two scenarios:
1. The application has not started.
2. The startup path of the application (OTEL_GO_AUTO_TARGET_EXE) is incorrect.
The agent log reports an error:
traces export: failed to exit idle mode: dns resolver: missing address
This generally occurs when the access point does not have the http:// prefix added.

Adding Manual Instrumentation

To increase the flexibility of instrumentation, the eBPF agent supports custom instrumentation, allowing you to add custom span information related to business logic and internal features. The sample code is as follows:
import (
...
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
...
)
...

var tracer = otel.Tracer("rolldice") // Create a Tracer.

...

func (s *Server) rollDice(w http.ResponseWriter, req *http.Request) {
ctx, span := tracer.Start(req.Context(), "roll") // Create a span.
defer span.End()

n := s.rand.Intn(6) + 1

_, err := s.db.ExecContext(ctx, "INSERT INTO results (roll_value) VALUES (?)", n)
if err != nil {
panic(err)
}

span.SetAttributes(attribute.Int("roll.value", n)) // Add span attributes.

fmt.Fprintf(w, "%v", n)
}

Example of eBPF Code for Accessing

Note:
Below are multiple code examples of access APM via eBPF agent, helping users easily report their business trace data to APM.
When reporting data using eBPF agents, minimal changes to the existing business code are required, but attention to some details, such as the passing of context in the code, is necessary.

Database Operation Programs Providing External APIs

The main feature of this project is to provide an HTTP API for external access. Calling this API allows you to operate the SQLite database. It is implemented based on the standard libraries net/http and database/sql of the Go language.
package main
import (
"database/sql"
"fmt"
"net/http"
"os"
_ "github.com/mattn/go-sqlite3"
"go.uber.org/zap"
)

const (
sqlQuery = "SELECT * FROM contacts"
dbName = "test.db"
tableDefinition = `CREATE TABLE contacts (
contact_id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
email TEXT NOT NULL,
phone TEXT NOT NULL);`

tableInsertion = `INSERT INTO 'contacts'
('first_name', 'last_name', 'email', 'phone') VALUES
('Moshe', 'Levi', 'moshe@gmail.com', '052-1234567');`
)

type Server struct {
db *sql.DB
}
// Initialize the database.
func CreateDb() {
file, err := os.Create(dbName)
if err != nil {
panic(err)
}
err = file.Close()
if err != nil {
panic(err)
}
}

func NewServer() *Server {
CreateDb()
database, err := sql.Open("sqlite3", dbName)
if err != nil {
panic(err)
}
_, err = database.Exec(tableDefinition)
if err != nil {
panic(err)
}
return &Server{
db: database,
}
}

func (s *Server) queryDb(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
conn, err := s.db.Conn(ctx)
if err != nil {
panic(err)
}
// Note that you must pass ctx or req.Context() here to ensure that the HTTP request and database operation records can be maintained in the same trace.
// If the request context is not passed here and it is written as s.db.Exec(tableInsertion), the trace will be interrupted, and the HTTP span and database span will appear in two separate traces!
_, err = s.db.ExecContext(ctx, tableInsertion)
if err != nil {
panic(err)
}
rows, err := conn.QueryContext(req.Context(), sqlQuery)
if err != nil {
panic(err)
}
logger.Info("queryDb called")
for rows.Next() {
var id int
var firstName string
var lastName string
var email string
var phone string
err := rows.Scan(&id, &firstName, &lastName, &email, &phone)
if err != nil {
panic(err)
}
fmt.Fprintf(w, "ID: %d, firstName: %s, lastName: %s, email: %s, phone: %s\n", id, firstName, lastName, email, phone)
}
}
Note:
Please pay attention to the comments in the code. Be sure to correctly pass the context to properly construct the parent-child relationship between spans and ensure the trace does not break.
Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback

Contact Us

Contact our sales team or business advisors to help your business.

Technical Support

Open a ticket if you're looking for further assistance. Our Ticket is 7x24 available.

7x24 Phone Support
Hong Kong, China
+852 800 906 020 (Toll Free)
United States
+1 844 606 0804 (Toll Free)
United Kingdom
+44 808 196 4551 (Toll Free)
Canada
+1 888 605 7930 (Toll Free)
Australia
+61 1300 986 386 (Toll Free)
EdgeOne hotline
+852 300 80699
More local hotlines coming soon