Skip to content

Commit 6cad423

Browse files
authored
Add prometheus metric support. (#92)
1 parent 55c1207 commit 6cad423

File tree

3 files changed

+252
-16
lines changed

3 files changed

+252
-16
lines changed

app/server/server.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ import (
99
"os"
1010
"slices"
1111
"strings"
12+
"time"
1213

14+
prom "github.com/prometheus/client_golang/prometheus"
1315
"github.com/temporalio/reference-app-orders-go/app/billing"
1416
"github.com/temporalio/reference-app-orders-go/app/config"
1517
"github.com/temporalio/reference-app-orders-go/app/db"
1618
"github.com/temporalio/reference-app-orders-go/app/fraud"
1719
"github.com/temporalio/reference-app-orders-go/app/order"
1820
"github.com/temporalio/reference-app-orders-go/app/shipment"
21+
"github.com/uber-go/tally/v4"
22+
"github.com/uber-go/tally/v4/prometheus"
1923
"go.temporal.io/sdk/client"
24+
sdktally "go.temporal.io/sdk/contrib/tally"
2025
"go.temporal.io/sdk/log"
2126
"golang.org/x/sync/errgroup"
2227
)
@@ -35,6 +40,7 @@ import (
3540
func CreateClientOptionsFromEnv() (client.Options, error) {
3641
hostPort := os.Getenv("TEMPORAL_ADDRESS")
3742
namespaceName := os.Getenv("TEMPORAL_NAMESPACE")
43+
logger := slog.Default()
3844

3945
// Must explicitly set the Namepace for non-cloud use.
4046
if strings.Contains(hostPort, ".tmprl.cloud:") && namespaceName == "" {
@@ -49,7 +55,7 @@ func CreateClientOptionsFromEnv() (client.Options, error) {
4955
clientOpts := client.Options{
5056
HostPort: hostPort,
5157
Namespace: namespaceName,
52-
Logger: log.NewStructuredLogger(slog.Default()),
58+
Logger: log.NewStructuredLogger(logger),
5359
}
5460

5561
if certPath := os.Getenv("TEMPORAL_TLS_CERT"); certPath != "" {
@@ -63,9 +69,44 @@ func CreateClientOptionsFromEnv() (client.Options, error) {
6369
}
6470
}
6571

72+
endpoint := os.Getenv("TEMPORAL_METRICS_ENDPOINT")
73+
if endpoint != "" {
74+
scope, err := newPrometheusScope(prometheus.Configuration{
75+
ListenAddress: endpoint,
76+
TimerType: "histogram",
77+
}, logger)
78+
if err != nil {
79+
return clientOpts, fmt.Errorf("failed to create metrics scope: %w", err)
80+
}
81+
clientOpts.MetricsHandler = sdktally.NewMetricsHandler(scope)
82+
}
83+
6684
return clientOpts, nil
6785
}
6886

87+
func newPrometheusScope(c prometheus.Configuration, logger *slog.Logger) (tally.Scope, error) {
88+
reporter, err := c.NewReporter(
89+
prometheus.ConfigurationOptions{
90+
Registry: prom.NewRegistry(),
91+
OnError: func(err error) {
92+
logger.Error("error in prometheus reporter", "error", err)
93+
},
94+
},
95+
)
96+
if err != nil {
97+
return nil, fmt.Errorf("error creating prometheus reporter: %w", err)
98+
}
99+
scopeOpts := tally.ScopeOptions{
100+
CachedReporter: reporter,
101+
Separator: prometheus.DefaultSeparator,
102+
SanitizeOptions: &sdktally.PrometheusSanitizeOptions,
103+
}
104+
scope, _ := tally.NewRootScope(scopeOpts, time.Second)
105+
scope = sdktally.NewPrometheusNamingScope(scope)
106+
107+
return scope, nil
108+
}
109+
69110
// RunWorkers runs workers for the requested services.
70111
func RunWorkers(ctx context.Context, config config.AppConfig, client client.Client, services []string) error {
71112
ctx, cancel := context.WithCancel(ctx)
@@ -150,10 +191,6 @@ func runAPIServer(ctx context.Context, hostPort string, router http.Handler, log
150191
return nil
151192
}
152193

153-
func serverHostPort(config config.AppConfig, port int32) string {
154-
return fmt.Sprintf("%s:%d", config.BindOnIP, port)
155-
}
156-
157194
// RunAPIServers runs API servers for the requested services.
158195
func RunAPIServers(ctx context.Context, config config.AppConfig, client client.Client, services []string) error {
159196
ctx, cancel := context.WithCancel(ctx)

go.mod

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
module github.com/temporalio/reference-app-orders-go
22

33
go 1.22.0
4+
45
require (
56
github.com/google/uuid v1.6.0
67
github.com/jmoiron/sqlx v1.4.0
8+
github.com/prometheus/client_golang v1.16.0
79
github.com/spf13/cobra v1.8.1
810
github.com/stretchr/testify v1.10.0
911
github.com/testcontainers/testcontainers-go/modules/mongodb v0.33.0
12+
github.com/uber-go/tally/v4 v4.1.17
1013
go.mongodb.org/mongo-driver v1.17.0
1114
go.temporal.io/api v1.44.1
1215
go.temporal.io/sdk v1.33.0
16+
go.temporal.io/sdk/contrib/opentelemetry v0.6.0
17+
go.temporal.io/sdk/contrib/tally v0.2.0
1318
golang.org/x/sync v0.11.0
1419
modernc.org/sqlite v1.34.1
1520
)
@@ -18,7 +23,9 @@ require (
1823
dario.cat/mergo v1.0.0 // indirect
1924
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
2025
github.com/Microsoft/go-winio v0.6.2 // indirect
26+
github.com/beorn7/perks v1.0.1 // indirect
2127
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
28+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2229
github.com/containerd/containerd v1.7.27 // indirect
2330
github.com/containerd/log v0.1.0 // indirect
2431
github.com/containerd/platforms v0.2.1 // indirect
@@ -36,6 +43,7 @@ require (
3643
github.com/go-ole/go-ole v1.2.6 // indirect
3744
github.com/gogo/protobuf v1.3.2 // indirect
3845
github.com/golang/mock v1.6.0 // indirect
46+
github.com/golang/protobuf v1.5.4 // indirect
3947
github.com/golang/snappy v0.0.4 // indirect
4048
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
4149
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
@@ -45,6 +53,7 @@ require (
4553
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
4654
github.com/magiconair/properties v1.8.7 // indirect
4755
github.com/mattn/go-isatty v0.0.20 // indirect
56+
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
4857
github.com/moby/docker-image-spec v1.3.1 // indirect
4958
github.com/moby/patternmatcher v0.6.0 // indirect
5059
github.com/moby/sys/sequential v0.5.0 // indirect
@@ -61,6 +70,9 @@ require (
6170
github.com/pkg/errors v0.9.1 // indirect
6271
github.com/pmezard/go-difflib v1.0.0 // indirect
6372
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
73+
github.com/prometheus/client_model v0.3.0 // indirect
74+
github.com/prometheus/common v0.42.0 // indirect
75+
github.com/prometheus/procfs v0.10.1 // indirect
6476
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
6577
github.com/robfig/cron v1.2.0 // indirect
6678
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
@@ -71,15 +83,17 @@ require (
7183
github.com/testcontainers/testcontainers-go v0.33.0 // indirect
7284
github.com/tklauser/go-sysconf v0.3.12 // indirect
7385
github.com/tklauser/numcpus v0.6.1 // indirect
86+
github.com/twmb/murmur3 v1.1.8 // indirect
7487
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
7588
github.com/xdg-go/scram v1.1.2 // indirect
7689
github.com/xdg-go/stringprep v1.0.4 // indirect
7790
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
7891
github.com/yusufpapurcu/wmi v1.2.3 // indirect
7992
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
80-
go.opentelemetry.io/otel v1.24.0 // indirect
81-
go.opentelemetry.io/otel/metric v1.24.0 // indirect
82-
go.opentelemetry.io/otel/trace v1.24.0 // indirect
93+
go.opentelemetry.io/otel v1.27.0 // indirect
94+
go.opentelemetry.io/otel/metric v1.27.0 // indirect
95+
go.opentelemetry.io/otel/trace v1.27.0 // indirect
96+
go.uber.org/atomic v1.11.0 // indirect
8397
golang.org/x/crypto v0.31.0 // indirect
8498
golang.org/x/net v0.33.0 // indirect
8599
golang.org/x/sys v0.28.0 // indirect

0 commit comments

Comments
 (0)