Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,34 @@ func init() {
### Collecting Metrics

Once the collector has been initialized with `instana.InitCollector`, application metrics such as memory, CPU consumption, active goroutine count etc will be automatically collected and reported to the Agent without further actions or configurations to the SDK.

#### Configuring Metrics Transmission Interval

By default, metrics are transmitted to the Instana Agent every 1000ms (1 second). You can customize this interval to suit your application's needs:

**Via Environment Variable:**
```bash
export INSTANA_METRICS_TRANSMISSION_DELAY=2000 # 2 seconds
```

**Via Code Configuration:**
```go
col = instana.InitCollector(&instana.Options{
Service: "My app",
Metrics: instana.MetricsOptions{
TransmissionDelay: 3000, // 3 seconds
},
})
```

**Configuration Rules:**
- Valid range: 1000ms to 5000ms
Comment thread
Angith marked this conversation as resolved.
Outdated
- Default: 1000ms (if not specified or invalid)
- Values above 5000ms are automatically capped
- Environment variable takes precedence over code configuration

For detailed examples and use cases, see [example/metrics-interval/](example/metrics-interval/).

This data is then already available in the dashboard.

### Tracing Calls
Expand Down
78 changes: 78 additions & 0 deletions example/metrics-interval/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Configurable Metrics Transmission Interval Examples

This directory contains examples demonstrating how to configure the metrics transmission interval in the Instana Go Sensor.

## Overview

The Instana Go Sensor allows you to configure how frequently metrics are transmitted to the Instana agent. By default, metrics are sent every 1000ms (1 second), but this can be customized based on your application's needs.

## Configuration Methods

### 1. Environment Variable (env-config/)

Configure the interval using the `INSTANA_METRICS_TRANSMISSION_DELAY` environment variable.

```bash
export INSTANA_METRICS_TRANSMISSION_DELAY=2000
go run example/metrics-interval/env-config/main.go
```

**Advantages:**
- No code changes required
- Easy to adjust per environment (dev, staging, prod)
- Takes precedence over code configuration

### 2. Code Configuration (code-config/)

Configure the interval programmatically in your application code.

```go
instana.InitCollector(&instana.Options{
Service: "my-service",
Metrics: instana.MetricsOptions{
TransmissionDelay: 3000, // 3 seconds
},
})
```

**Advantages:**
- Explicit and visible in code
- Can be set conditionally based on application logic
- Type-safe configuration

## Configuration Rules

- **Valid Range**: 1000ms to 5000ms
- **Default**: 1000ms (if not specified or invalid)
- **Maximum Cap**: Values above 5000ms are automatically capped at 5000ms
- **Invalid Values**: Non-numeric, zero, or negative values fall back to default 1000ms
- **Precedence**: Environment variable > Code configuration > Default

## Running the Examples

### Environment Variable Example
environment variable is set programmatically in the code.
```bash
cd example/metrics-interval/env-config
go run main.go
```

### Code Configuration Example
```bash
cd example/metrics-interval/code-config
go run main.go
```

## Validation and Error Handling

The sensor validates all configuration values and provides warning logs for invalid inputs:

- **Invalid format**: Falls back to default 1000ms with warning
- **Out of range**: Caps at 5000ms or uses default for values ≤ 1000
- **Graceful degradation**: Application continues running with safe defaults

## See Also

- [Main Documentation](../../README.md)
- [Options Documentation](../../docs/options.md)
- [Instana Go Sensor API](https://pkg.go.dev/github.com/instana/go-sensor)
110 changes: 110 additions & 0 deletions example/metrics-interval/code-config/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-FileCopyrightText: 2026 IBM Corp.
//
// SPDX-License-Identifier: MIT

package main

import (
"fmt"
"log"
"net/http"
"os"
"os/signal"
"time"

instana "github.com/instana/go-sensor"
)

func main() {
fmt.Println("=== Instana Metrics Transmission Interval - Code Configuration ===")
fmt.Println()

// Example 1: Configure metrics transmission interval via code
fmt.Println("Example 1: Setting custom interval to 3000ms (3 seconds)")

opts := &instana.Options{
Service: "metrics-interval-code-example-2",
Metrics: instana.MetricsOptions{
TransmissionDelay: 3000, // 3000 milliseconds = 3 seconds
},
}

col := instana.InitCollector(opts)

fmt.Println("✓ Instana collector initialized")
fmt.Println("✓ Metrics will be transmitted every 3000ms")
fmt.Println()

// Example 2: Different configurations
fmt.Println("Other configuration examples:")
fmt.Println()

// Fast interval for high-frequency monitoring
fmt.Println(" Fast interval (500ms):")
fmt.Println(" Metrics: instana.MetricsOptions{")
fmt.Println(" TransmissionDelay: 500,")
fmt.Println(" }")
fmt.Println()

// Slow interval for resource-constrained environments
fmt.Println(" Slow interval (5000ms - maximum):")
fmt.Println(" Metrics: instana.MetricsOptions{")
fmt.Println(" TransmissionDelay: 5000,")
fmt.Println(" }")
fmt.Println()

// Default behavior
fmt.Println(" Default interval (1000ms):")
fmt.Println(" Metrics: instana.MetricsOptions{")
fmt.Println(" TransmissionDelay: 0, // or omit the field")
fmt.Println(" }")
fmt.Println()

fmt.Println("Configuration rules:")
fmt.Println(" - Valid range: 1ms to 5000ms")
fmt.Println(" - Values above 5000ms are automatically capped at 5000ms")
fmt.Println(" - Zero or negative values use default 1000ms")
fmt.Println(" - Environment variable INSTANA_METRICS_TRANSMISSION_DELAY takes precedence")
fmt.Println()

// Simulate application running
go func() {
http.HandleFunc("/endpoint", instana.TracingHandlerFunc(col, "/endpoint", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))

log.Fatal(http.ListenAndServe(":7070", nil))
}()

go func() {
ticker := time.NewTicker(5 * time.Second)

client := &http.Client{
Timeout: 10 * time.Second,
}

for range ticker.C {
url := "http://localhost:7070/endpoint"
// Create request
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
// Send request
_, err = client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
}
}()

fmt.Println("Please go to the Instana UI to see metrics")
fmt.Println("Application running... (press Ctrl+C to exit)")

stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
fmt.Println("Application stopped.")
}
88 changes: 88 additions & 0 deletions example/metrics-interval/env-config/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-FileCopyrightText: 2026 IBM Corp.
//
// SPDX-License-Identifier: MIT

package main

import (
"fmt"
"log"
"net/http"
"os"
"os/signal"
"time"

instana "github.com/instana/go-sensor"
)

func main() {
// Example: Configure metrics transmission interval via environment variable
// Set INSTANA_METRICS_TRANSMISSION_DELAY before starting the application

// For demonstration, we'll set it programmatically here
// In production, set this via your deployment configuration
os.Setenv("INSTANA_METRICS_TRANSMISSION_DELAY", "2000")

fmt.Println("=== Instana Metrics Transmission Interval - ENV Configuration ===")
fmt.Println()
fmt.Println("Environment variable INSTANA_METRICS_TRANSMISSION_DELAY=2000")
fmt.Println("This will configure metrics to be transmitted every 2000ms (2 seconds)")
fmt.Println()

// Initialize the Instana collector with default options
// The environment variable will be automatically applied
col := instana.InitCollector(&instana.Options{
Service: "metrics-interval-env-example",
})

fmt.Println("✓ Instana collector initialized")
fmt.Println("✓ Metrics will be transmitted every 2000ms")
fmt.Println()
fmt.Println("Valid values:")
fmt.Println(" - Minimum: 1ms")
fmt.Println(" - Maximum: 5000ms (values above will be capped)")
fmt.Println(" - Default: 1000ms (if not specified or invalid)")
fmt.Println()
fmt.Println("Invalid values (non-numeric, negative, zero) will fall back to default 1000ms")
fmt.Println()

// Simulate application running
go func() {
http.HandleFunc("/endpoint", instana.TracingHandlerFunc(col, "/endpoint", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))

log.Fatal(http.ListenAndServe(":7070", nil))
}()

go func() {
ticker := time.NewTicker(5 * time.Second)

client := &http.Client{
Timeout: 10 * time.Second,
}

for range ticker.C {
url := "http://localhost:7070/endpoint"
// Create request
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
// Send request
_, err = client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
}
}()

fmt.Println("Please go to the Instana UI to see metrics")
fmt.Println("Application running... (press Ctrl+C to exit)")
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
fmt.Println("Application stopped.")
}
35 changes: 35 additions & 0 deletions meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,31 @@ type meterS struct {
done chan struct{}
}

// MetricsOptions contains configuration for metrics collection and transmission
type MetricsOptions struct {
// TransmissionDelay specifies the interval in milliseconds between metrics transmissions
// to the Instana agent.
//
// Default: 1000 (1 second)
// Minimum: 1000 (enforced via validation, values < 1000 use default)
// Maximum: 5000 (5 seconds, values above are capped with warning)
//
// This value can be configured via:
// - Environment variable: INSTANA_METRICS_TRANSMISSION_DELAY
// - Code: opts.Metrics.TransmissionDelay = 2000
//
// Configuration precedence: ENV > code > default
//
// Example:
// opts := &instana.Options{
// Service: "MyApp",
// Metrics: instana.MetricsOptions{
// TransmissionDelay: 2000, // 2 seconds
// },
// }
TransmissionDelay int
}

func newMeter(logger LeveledLogger) *meterS {
logger.Debug("initializing meter")

Expand Down Expand Up @@ -62,6 +87,16 @@ func (m *meterS) Stop() {
m.done <- struct{}{}
}

func getTransmissionDelay(options *Options) time.Duration {
interval := time.Duration(options.Metrics.TransmissionDelay) * time.Millisecond
// Safety check: fallback to default if interval becomes negative,
Comment thread
Angith marked this conversation as resolved.
Outdated
// possibly due to missing TransmissionDelay during sensor re-initialization.
if interval <= 0 {
interval = 1000 * time.Millisecond
}
return interval
}

func (m *meterS) collectMemoryMetrics() acceptor.MemoryStats {
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
Expand Down
Loading
Loading