Skip to content

Commit fdca94b

Browse files
committed
commit the instruments
1 parent 6a8a792 commit fdca94b

4 files changed

Lines changed: 284 additions & 0 deletions

File tree

telemetry/config_test.go

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package telemetry
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"go.yaml.in/yaml/v3"
8+
)
9+
10+
func TestCosmosExtraUnmarshal(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
yaml string
14+
expected extraConfig
15+
}{
16+
{
17+
name: "instruments with empty config",
18+
yaml: `
19+
cosmos_extra:
20+
instruments:
21+
host: {}
22+
runtime: {}
23+
`,
24+
expected: extraConfig{
25+
CosmosExtra: &cosmosExtra{
26+
Instruments: map[string]map[string]any{
27+
"host": {},
28+
"runtime": {},
29+
},
30+
},
31+
},
32+
},
33+
{
34+
name: "instruments with options",
35+
yaml: `
36+
cosmos_extra:
37+
instruments:
38+
host: {}
39+
diskio:
40+
disable_virtual_device_filter: true
41+
`,
42+
expected: extraConfig{
43+
CosmosExtra: &cosmosExtra{
44+
Instruments: map[string]map[string]any{
45+
"host": {},
46+
"diskio": {
47+
"disable_virtual_device_filter": true,
48+
},
49+
},
50+
},
51+
},
52+
},
53+
{
54+
name: "instruments with propagators",
55+
yaml: `
56+
cosmos_extra:
57+
instruments:
58+
host: {}
59+
propagators:
60+
- tracecontext
61+
- baggage
62+
`,
63+
expected: extraConfig{
64+
CosmosExtra: &cosmosExtra{
65+
Instruments: map[string]map[string]any{
66+
"host": {},
67+
},
68+
Propagators: []string{"tracecontext", "baggage"},
69+
},
70+
},
71+
},
72+
{
73+
name: "full config",
74+
yaml: `
75+
cosmos_extra:
76+
trace_file: /tmp/traces.json
77+
metrics_file: /tmp/metrics.json
78+
instruments:
79+
host: {}
80+
runtime: {}
81+
diskio:
82+
disable_virtual_device_filter: true
83+
propagators:
84+
- tracecontext
85+
`,
86+
expected: extraConfig{
87+
CosmosExtra: &cosmosExtra{
88+
TraceFile: "/tmp/traces.json",
89+
MetricsFile: "/tmp/metrics.json",
90+
Instruments: map[string]map[string]any{
91+
"host": {},
92+
"runtime": {},
93+
"diskio": {
94+
"disable_virtual_device_filter": true,
95+
},
96+
},
97+
Propagators: []string{"tracecontext"},
98+
},
99+
},
100+
},
101+
{
102+
name: "empty cosmos_extra (null)",
103+
yaml: `
104+
cosmos_extra:
105+
`,
106+
expected: extraConfig{
107+
CosmosExtra: nil, // YAML with just "cosmos_extra:" and no value results in nil
108+
},
109+
},
110+
{
111+
name: "empty cosmos_extra (empty object)",
112+
yaml: `
113+
cosmos_extra: {}
114+
`,
115+
expected: extraConfig{
116+
CosmosExtra: &cosmosExtra{},
117+
},
118+
},
119+
{
120+
name: "no cosmos_extra",
121+
yaml: `
122+
some_other_key: value
123+
`,
124+
expected: extraConfig{
125+
CosmosExtra: nil,
126+
},
127+
},
128+
{
129+
name: "realistic otel.yaml with cosmos_extra",
130+
yaml: `
131+
file_format: "1.0-rc.3"
132+
resource:
133+
attributes:
134+
- name: service.name
135+
value: simapp
136+
137+
tracer_provider:
138+
processors:
139+
- batch:
140+
exporter:
141+
otlp_grpc:
142+
endpoint: http://localhost:4317
143+
144+
meter_provider:
145+
readers:
146+
- pull:
147+
exporter:
148+
prometheus/development:
149+
host: 0.0.0.0
150+
port: 9464
151+
152+
cosmos_extra:
153+
instruments:
154+
host: {}
155+
runtime: {}
156+
diskio:
157+
disable_virtual_device_filter: true
158+
propagators:
159+
- tracecontext
160+
`,
161+
expected: extraConfig{
162+
CosmosExtra: &cosmosExtra{
163+
Instruments: map[string]map[string]any{
164+
"host": {},
165+
"runtime": {},
166+
"diskio": {
167+
"disable_virtual_device_filter": true,
168+
},
169+
},
170+
Propagators: []string{"tracecontext"},
171+
},
172+
},
173+
},
174+
}
175+
176+
for _, tc := range tests {
177+
t.Run(tc.name, func(t *testing.T) {
178+
var cfg extraConfig
179+
err := yaml.Unmarshal([]byte(tc.yaml), &cfg)
180+
require.NoError(t, err)
181+
182+
if tc.expected.CosmosExtra == nil {
183+
require.Nil(t, cfg.CosmosExtra)
184+
return
185+
}
186+
187+
require.NotNil(t, cfg.CosmosExtra)
188+
require.Equal(t, tc.expected.CosmosExtra.TraceFile, cfg.CosmosExtra.TraceFile)
189+
require.Equal(t, tc.expected.CosmosExtra.MetricsFile, cfg.CosmosExtra.MetricsFile)
190+
require.Equal(t, tc.expected.CosmosExtra.Propagators, cfg.CosmosExtra.Propagators)
191+
192+
require.Equal(t, len(tc.expected.CosmosExtra.Instruments), len(cfg.CosmosExtra.Instruments),
193+
"instruments count mismatch")
194+
195+
for name, expectedOpts := range tc.expected.CosmosExtra.Instruments {
196+
actualOpts, ok := cfg.CosmosExtra.Instruments[name]
197+
require.True(t, ok, "missing instrument: %s", name)
198+
require.Equal(t, len(expectedOpts), len(actualOpts),
199+
"options count mismatch for instrument %s", name)
200+
201+
for key, expectedVal := range expectedOpts {
202+
actualVal, ok := actualOpts[key]
203+
require.True(t, ok, "missing option %s for instrument %s", key, name)
204+
require.Equal(t, expectedVal, actualVal,
205+
"option value mismatch for %s.%s", name, key)
206+
}
207+
}
208+
})
209+
}
210+
}

telemetry/registry/registry.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Package registry provides an instrument registry for telemetry instrumentation.
2+
package registry
3+
4+
import "fmt"
5+
6+
// Instrument defines an interface for telemetry instruments that can self-register.
7+
type Instrument interface {
8+
// Name returns the instrument's identifier used in configuration.
9+
Name() string
10+
// Start initializes the instrument with the provided configuration map.
11+
Start(config map[string]any) error
12+
}
13+
14+
var instruments = map[string]Instrument{}
15+
16+
// Register registers an instrument for use in configuration.
17+
// This is typically called from an instrument package's init() function.
18+
func Register(i Instrument) {
19+
if _, exists := instruments[i.Name()]; exists {
20+
panic(fmt.Sprintf("telemetry: instrument %q already registered", i.Name()))
21+
}
22+
instruments[i.Name()] = i
23+
}
24+
25+
// Get returns a registered instrument by name, or nil if not found.
26+
func Get(name string) Instrument {
27+
return instruments[name]
28+
}

telemetry/util/host/host.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Package host provides a telemetry instrument wrapper for host-level metrics.
2+
package host
3+
4+
import (
5+
"go.opentelemetry.io/contrib/instrumentation/host"
6+
7+
"github.com/cosmos/cosmos-sdk/telemetry/registry"
8+
)
9+
10+
// Name is the instrument name used in configuration.
11+
const Name = "host"
12+
13+
func init() {
14+
registry.Register(instrument{})
15+
}
16+
17+
type instrument struct{}
18+
19+
func (instrument) Name() string { return Name }
20+
21+
func (instrument) Start(_ map[string]any) error {
22+
return host.Start()
23+
}

telemetry/util/runtime/runtime.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Package runtime provides a telemetry instrument wrapper for Go runtime metrics.
2+
package runtime
3+
4+
import (
5+
"go.opentelemetry.io/contrib/instrumentation/runtime"
6+
7+
"github.com/cosmos/cosmos-sdk/telemetry/registry"
8+
)
9+
10+
// Name is the instrument name used in configuration.
11+
const Name = "runtime"
12+
13+
func init() {
14+
registry.Register(instrument{})
15+
}
16+
17+
type instrument struct{}
18+
19+
func (instrument) Name() string { return Name }
20+
21+
func (instrument) Start(_ map[string]any) error {
22+
return runtime.Start()
23+
}

0 commit comments

Comments
 (0)