English | 中文
goner/otel/meter
Overview
goner/otel/meter is a component in the Gone framework that supports OpenTelemetry metrics collection functionality. This module provides integration with the OpenTelemetry metrics system, enabling applications to create, record, and export various metrics data, helping developers monitor application performance, resource usage, and business metrics.
Key Features
- Provides initialization and configuration of the OpenTelemetry metrics system
- Supports creating and managing various metric types (Counter, Gauge, Histogram, etc.)
- Defaults to providing a standard output (stdout) metrics exporter
- Integrates with Gone framework's lifecycle management to ensure proper flushing and shutdown of the metrics system
- Supports multiple metric export formats and protocols
Submodules
goner/otel/meter/http: Provides OpenTelemetry metrics exporter based on HTTP protocol
goner/otel/meter/grpc: Provides OpenTelemetry metrics exporter based on gRPC protocol
goner/otel/meter/prometheus: Provides metrics exporter compatible with Prometheus
goner/otel/meter/prometheus/gin: Provides Prometheus metrics exposure interface integrated with Gin framework
Installation
# Install basic metrics module
gonectl install goner/otel/meter
# Install HTTP exporter
gonectl install goner/otel/meter/http
# Install gRPC exporter
gonectl install goner/otel/meter/grpc
# Install Prometheus exporter
gonectl install goner/otel/meter/prometheus
# Install Prometheus Gin integration
gonectl install goner/otel/meter/prometheus/gin
If only installing goner/otel/meter, it will default to using the standard output (stdout) metrics exporter; you only need to install one of goner/otel/meter/http, goner/otel/meter/grpc, or goner/otel/meter/prometheus based on actual needs, as they already depend on goner/otel/meter and don't require manual installation of goner/otel/meter.
Simple Example
Demonstrates exporting metrics data to standard output (stdout) using the goner/otel/meter component
Execute the following commands
gonectl create -t otel/meter/simple simple-demo
cd simple-demo
go run .
Project Structure
.
├── go.mod
├── go.sum
├── main.go
└── module.load.go
Code
- module.load.go, generated by running
gonectl install goner/otel/meter.
// Code generated by gonectl. DO NOT EDIT.
package main
import(
"github.com/gone-io/gone/v2"
"github.com/gone-io/goner/g"
"github.com/gone-io/goner/otel/meter"
)
// load installed gone module LoadFunc
var loaders = []gone.LoadFunc{
meter.Register,
}
func GoneModuleLoad(loader gone.Loader) error {
var ops []*g.LoadOp
for _, f := range loaders {
ops = append(ops, g.F(f))
}
return g.BuildOnceLoadFunc(ops...)(loader)
}
package main
import (
"context"
"github.com/gone-io/gone/v2"
"go.opentelemetry.io/otel/metric"
"os"
"time"
)
func main() {
_ = os.Setenv("GONE_OTEL_SERVICE_NAME", "simple meter demo")
gone.
NewApp(GoneModuleLoad).
Run(func(meter metric.Meter, logger gone.Logger) {
apiCounter, err := meter.Int64Counter(
"api.counter",
metric.WithDescription("API call count"),
metric.WithUnit("{count}"),
)
if err != nil {
logger.Errorf("create meter err:%v", err)
return
}
for i := 0; i < 5; i++ {
time.Sleep(1 * time.Second)
apiCounter.Add(context.Background(), 1)
}
})
}
Output
{
"Resource": [
{
"Key": "service.name",
"Value": {
"Type": "STRING",
"Value": "simple meter demo"
}
},
{
"Key": "telemetry.sdk.language",
"Value": {
"Type": "STRING",
"Value": "go"
}
},
{
"Key": "telemetry.sdk.name",
"Value": {
"Type": "STRING",
"Value": "opentelemetry"
}
},
{
"Key": "telemetry.sdk.version",
"Value": {
"Type": "STRING",
"Value": "1.35.0"
}
}
],
"ScopeMetrics": [
{
"Scope": {
"Name": "",
"Version": "",
"SchemaURL": "",
"Attributes": null
},
"Metrics": [
{
"Name": "api.counter",
"Description": "API call count",
"Unit": "{count}",
"Data": {
"DataPoints": [
{
"Attributes": [],
"StartTime": "0001-01-01T00:00:00Z",
"Time": "0001-01-01T00:00:00Z",
"Value": 5
}
],
"Temporality": "CumulativeTemporality",
"IsMonotonic": true
}
}
]
}
]
}
Using Other Exporters
Advanced Configuration
Custom Exporter
To implement a custom metrics exporter, you can implement the metric.Exporter interface and inject it into the framework:
var _ metric.Exporter = (*CustomExporter)(nil)
type CustomExporter struct {
// Implement metric.Exporter interface
}
// Define load function
func RegisterCustomExporter(loader gone.Loader) {
return loader.Load(&CustomExporter{})
}
//....
// Load during startup
// gone.Loads(RegisterCustomExporter)
//...
Checking if OpenTelemetry/Meter is Used in Custom Components
type YourComponent struct {
isOtelMeterLoaded g.IsOtelMeterLoaded `gone:"*"`
}
func(s*YourComponent)BusinessLogic(){
if s.isOtelMeterLoaded{
// Handle metrics collection logic
} else{
// Fallback handling without metrics collection
}
}
Best Practices
- Meaningful Metric Names: Use names that reflect the actual meaning of the metric.
- Proper Units and Descriptions: Add clear units and descriptions to metrics for better understanding.
- Appropriate Metric Types: Choose suitable metric types (Counter, Gauge, Histogram, etc.) based on business needs.
- Meaningful Labels: Use labels to categorize and filter metrics, but avoid excessive label combinations.
- Regular Data Flushing: Ensure metrics data is exported and viewed in a timely manner.
FAQ
Metrics Not Exported Correctly
- Verify collector address and port are correct
- Confirm network connection is working
- Check application logs for export errors
Incomplete Metrics Data
- Verify metrics creation and recording are correct
- Ensure application runs long enough to collect data
- Validate metrics collection frequency is appropriate
- Reduce number of high-frequency recorded metrics
- Optimize batch configuration
- Reduce unnecessary labels and attributes
References