Skip to content

Commit 8f6317f

Browse files
committed
Update docs
1 parent 62a512a commit 8f6317f

File tree

8 files changed

+152
-52
lines changed

8 files changed

+152
-52
lines changed

README.md

Lines changed: 130 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,50 @@
11
# Easy metrics (em)
2-
Shorthand for [OTEL](https://github.com/open-telemetry/opentelemetry-go) instrumentation initialization.
3-
<br>
2+
Shorthand for [OTEL](https://github.com/open-telemetry/opentelemetry-go) metrics
3+
initialization.
4+
5+
46
## Usage
57
### TL;DR
68
#### [Simple usage](./example/simple_usage/main.go)
79
#### [Complete usage](./example/complete_usage/main.go)
810

9-
### Get the dependency:
11+
### Installation:
1012
```bash
1113
go get github.com/ofeefo/em
1214
```
1315

14-
### Define your instruments in a struct
16+
### Define your metrics within a struct
1517
```go
16-
type instruments struct{
17-
Counter64 em.I64Counter `id:"my_counter"`
18-
UpDownCounter64 em.I64Counter `id:"my_updown_counter"`
19-
GaugeF64 em.F64Gauge `id:"my_gauge"`
20-
// Histograms can use the 'buckets' tag to define explicit boundaries.
21-
HistogramF64 em.F64Histogram `id:"i_am_a_histogram" buckets:"1.0,2.0,3.0"`
18+
type metrics struct {
19+
Counter em.Counter[int64] `id:"a_counter"`
20+
Gauge em.Gauge[int64] `id:"a_gauge"`
21+
UpDownCounter em.UpDownCounter[float64] `id:"a_updowncounter"`
22+
Histogram em.Histogram[float64] `id:"a_histogram" buckets:"1.0,2.0,3.0"`
2223
}
2324
```
2425

25-
### When initializing your app
26+
### Setup your meter provider
2627

2728
```go
2829
// ...
29-
func main(){
30+
func main() {
3031
// Setup receives the application identifier and optional attributes.
31-
// It creates a basic OTEL setup to help you get started quickly.
32-
// For more advanced configurations (exporters, resources, etc.), use SetupWithMeter.
32+
// It creates a basic meter provider setup to help you get started quickly.
33+
// For more advanced configurations (exporters, resources, etc.),
34+
// use SetupWithMeter.
3335
err := em.Setup("my-app", attribute.String("some", "attr"))
3436
if err != nil {
3537
// ...
3638
}
3739

38-
// Initialize your instruments.
39-
// There's also a MustInit function, which will panic if initialization fails.
40-
i, err := em.Init[instruments]()
40+
// Initialize your metrics.
41+
m, err := em.Init[metrics]()
4142
if err != nil {
4243
//...
4344
}
4445

4546
// Record your measurements
46-
i.Counter64.Add(1, em.Attrs(attribute.String("some", "attr")))
47+
i.Counter.Inc(em.Attrs(attribute.String("some", "attr")))
4748

4849
// Serve your metrics.
4950
if err = http.ListenAndServe(":8080", promhttp.Handler()); err != nil {
@@ -53,46 +54,129 @@ func main(){
5354
```
5455

5556
## Features
56-
### Supported tags
57-
#### Instruments
58-
* `id [required]`: The instrument identifier.
59-
* `buckets [optional]`: Defines bucket boundaries for histograms.
57+
### Supported Metrics
58+
All available metrics are wrappers for the official [Go OTEL sdk](https://github.com/open-telemetry/opentelemetry-go),
59+
and can be created using both `int64` and `float64`, which are the available
60+
types for creating metrics with the official sdk (and limited in this package
61+
through the `n64` interface).
6062

61-
#### Nested or Embedded structs:
62-
* `attrs [optional]`: Comma-separated string attributes to identify specific instruments sets.
63+
### Counter
64+
```go
65+
type Counter[T n64] interface {
66+
// Add records a change of n to the counter.
67+
Add(n T, opts ...metric.AddOption)
6368

64-
### Supported instruments [int64/float64]:
65-
* `Counter`
66-
* `UpDownCounter`
67-
* `Gauge`
68-
* `Histogram`
69+
// AddCtx records a change of n to the counter.
70+
AddCtx(ctx context.Context, n T, opts ...metric.AddOption)
6971

70-
### Nested & Embedded structs
71-
The following example demonstrates how nested and embedded structs are supported:
72+
// Inc records a change of 1 to the counter.
73+
Inc(opts ...metric.AddOption)
7274

75+
// IncCtx records a change of 1 to the counter.
76+
IncCtx(ctx context.Context, opts ...metric.AddOption)
77+
}
78+
```
79+
### UpDownCounter
7380
```go
74-
type Embedded struct {
75-
Histogram em.I64Histogram `id:"example_embedded_histogram"`
76-
UpDownCounter em.F64UpDownCounter `id:"example_embedded_updowncounter"`
81+
type UpDownCounter[T n64] interface {
82+
// Add records a change of n to the counter.
83+
Add(n T, opts ...metric.AddOption)
84+
85+
// AddCtx records a change of n to the counter.
86+
AddCtx(ctx context.Context, n T, opts ...metric.AddOption)
87+
88+
// Inc records a change of 1 to the counter.
89+
Inc(opts ...metric.AddOption)
90+
91+
// IncCtx records a change of 1 to the counter.
92+
IncCtx(ctx context.Context, opts ...metric.AddOption)
93+
94+
// Dec records a change of -1 to the counter.
95+
Dec(opts ...metric.AddOption)
96+
97+
// DecCtx records a change of -1 to the counter.
98+
DecCtx(ctx context.Context, opts ...metric.AddOption)
7799
}
100+
```
101+
### Gauge
102+
```go
103+
type Gauge[T n64] interface {
104+
// Record records the value of n to the gauge.
105+
Record(n T, opts ...metric.RecordOption)
78106

79-
type nested struct {
80-
Counter em.F64Counter `id:"example_nested_counter"`
81-
Gauge em.F64Gauge `id:"example_nested_gauge"`
82-
MoreNest struct {
83-
Counter em.F64Counter `id:"example_more_nested_counter"`
84-
}
107+
// RecordCtx records the value of n to the gauge.
108+
RecordCtx(ctx context.Context, n T, opts ...metric.RecordOption)
109+
}
110+
111+
```
112+
### Histogram
113+
```go
114+
type Histogram[T n64] interface {
115+
// Record adds a value to the distribution.
116+
Record(n T, opts ...metric.RecordOption)
117+
118+
// RecordCtx adds a value to the distribution.
119+
RecordCtx(ctx context.Context, n T, opts ...metric.RecordOption)
120+
121+
// Measure creates a starting point using time.Now and returns a function
122+
// that records the time elapsed since the starting point. The returned
123+
// function may also receive record options to further support information
124+
// that may vary along a given procedure.
125+
Measure(transform timeSub[T], opts ...metric.RecordOption) func(opts ...metric.RecordOption)
126+
127+
// MeasureCtx creates a starting point using time.Now and returns a function
128+
// that records the time elapsed since the starting point. The returned
129+
// function may also receive record options to further support information
130+
// that may vary along a given procedure.
131+
MeasureCtx(ctx context.Context, transform timeTransform[T], opts ...metric.RecordOption) func(opts ...metric.RecordOption)
132+
}
133+
```
134+
135+
### Initialization Tags
136+
- `id [required]`: The metric identifier.
137+
- `buckets [optional]`: Defines bucket boundaries for histograms.
138+
- `attrs [optional]`: Defines additional identifiers for different components
139+
and [subsystems](#subsystems).
140+
141+
### Subsystems
142+
The following example demonstrates how to build metrics subsystems with nested
143+
and embedded structs:
144+
```go
145+
type PostgresMetrics struct{
146+
OpCount em.Counter[int64] `id:"operations_performed"`
147+
OpTime em.Histogram[int64] `id:"operation_time"`
148+
}
149+
150+
type dbMetrics struct {
151+
Master struct {
152+
PostgresMetrics
153+
WriteCounter em.Counter[int64] `id:"db_write_counter"`
154+
} `attrs:"sub, master"`
155+
156+
PostgresMetrics `attrs:"sub, replica"`
85157
}
86158

87-
type samplers struct {
88-
// Nested and embedded structs (and struct pointers) are supported.
89-
// Instruments in these structs inherit attributes both from the parent struct
90-
// initialization and through the 'attrs' tag.
91-
*Embedded `attrs:"sub,embedded"`
92-
Nested nested `attrs:"sub,nested"`
159+
type Metrics struct {
160+
DbMetrics dbMetrics `attrs:"sub,postgres"`
93161
}
94162
```
95163

164+
## Facilities
165+
- `timeSub[T]`: Functions that return the time elapsed since a given starting
166+
point. Already present in this package:
167+
- `Micros`
168+
- `Millis`
169+
- `Seconds`
170+
171+
### Initialization for tests
172+
When no `Setup` functions are called, a `noop` handler is used to avoid issues
173+
regarding metric identifier collision, allowing metrics to be initialized as usual
174+
without risking errors or nil pointer issues.
175+
176+
## Limitations
177+
1. Only synchronous metrics are supported.
178+
2. Initialization of instruments only allows for identifiers and
179+
bucket boundaries for `histograms`.
96180

97181

98182

base.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ import (
1010
"go.opentelemetry.io/otel/metric"
1111
)
1212

13+
// timeSub are functions that returns the time elapsed since a given starting
14+
// point.
1315
type timeSub[T n64] func(start time.Time) T
1416

17+
// n64 represents available types for creating metrics.
1518
type n64 interface {
1619
int64 | float64
1720
}

counter.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"go.opentelemetry.io/otel/metric"
99
)
1010

11+
// Counter is a synchronous Instrument which supports non-negative increments.
12+
// Complete docs:
13+
// https://opentelemetry.io/docs/specs/otel/metrics/api/#counter
1114
type Counter[T n64] interface {
1215
// Add records a change of n to the counter.
1316
Add(n T, opts ...metric.AddOption)

example/complete_usage/main.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ func main() {
5252
go func() {
5353
var i int64
5454
j := func() float64 { return float64(i) }
55-
done1 := s.Histogram.Measure(millis[float64], em.Attrs(attribute.String("your", "attr")))
56-
done2 := s2.Histogram.Measure(millis[float64], em.Attrs(attribute.String("your", "attr")))
55+
done1 := s.Histogram.Measure(em.Millis[float64], em.Attrs(attribute.String("your", "attr")))
56+
done2 := s2.Histogram.Measure(em.Millis[float64], em.Attrs(attribute.String("your", "attr")))
5757
for i = range 10 {
5858
// Layer 1 instruments
5959
s.Counter.Add(i, em.Attrs(attribute.String("your", "attr")))
@@ -94,7 +94,3 @@ func main() {
9494
panic(err)
9595
}
9696
}
97-
98-
func millis[T float64 | int64](start time.Time) T {
99-
return T(time.Since(start).Milliseconds())
100-
}

gauge.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"go.opentelemetry.io/otel/metric"
99
)
1010

11+
// Gauge is a synchronous Instrument which can be used to record non-additive
12+
// value(s).
13+
// Complete docs: https://opentelemetry.io/docs/specs/otel/metrics/api/#gauge
1114
type Gauge[T n64] interface {
1215
// Record records the value of n to the gauge.
1316
Record(n T, opts ...metric.RecordOption)

histogram.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import (
99
"go.opentelemetry.io/otel/metric"
1010
)
1111

12+
// Histogram is a synchronous Instrument which can be used to report arbitrary
13+
// values that are likely to be statistically meaningful. It is intended for
14+
// statistics such as histograms, summaries, and percentile.
15+
// Complete docs:
16+
// https://opentelemetry.io/docs/specs/otel/metrics/api/#histogram
1217
type Histogram[T n64] interface {
1318
// Record adds a value to the distribution.
1419
Record(n T, opts ...metric.RecordOption)

updown_counter.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"go.opentelemetry.io/otel/metric"
99
)
1010

11+
// UpDownCounter is a synchronous Instrument which supports increments and decrements.
12+
// Complete docs:
13+
// https://opentelemetry.io/docs/specs/otel/metrics/api/#updowncounter
1114
type UpDownCounter[T n64] interface {
1215
// Add records a change of n to the counter.
1316
Add(n T, opts ...metric.AddOption)

utils.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ func Attrs(attrs ...attribute.KeyValue) metric.MeasurementOption {
1111
return metric.WithAttributes(attrs...)
1212
}
1313

14+
// Millis returns the time elapsed since a given start point in milliseconds.
1415
func Millis[T n64](start time.Time) T {
1516
return T(time.Since(start).Milliseconds())
1617
}
1718

19+
// Micros returns the time elapsed since a given start point in microseconds.
1820
func Micros[T n64](start time.Time) T {
1921
return T(time.Since(start).Milliseconds())
2022
}
2123

24+
// Seconds returns the time elapsed since a given start point in seconds.
2225
func Seconds[T n64](start time.Time) T {
2326
return T(time.Since(start).Seconds())
2427
}

0 commit comments

Comments
 (0)