Skip to content

Commit 4c5bf42

Browse files
authored
feat: add option for exporting traces to a provided Honeycomb team (#4816)
1 parent 21e6494 commit 4c5bf42

File tree

7 files changed

+67
-9
lines changed

7 files changed

+67
-9
lines changed

cli/deployment/config.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,18 @@ func newConfig() *codersdk.DeploymentConfig {
289289
Default: "tls12",
290290
},
291291
},
292-
TraceEnable: &codersdk.DeploymentConfigField[bool]{
293-
Name: "Trace Enable",
294-
Usage: "Whether application tracing data is collected.",
295-
Flag: "trace",
292+
Trace: &codersdk.TraceConfig{
293+
Enable: &codersdk.DeploymentConfigField[bool]{
294+
Name: "Trace Enable",
295+
Usage: "Whether application tracing data is collected. It exports to a backend configured by environment variables. See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md",
296+
Flag: "trace",
297+
},
298+
HoneycombAPIKey: &codersdk.DeploymentConfigField[string]{
299+
Name: "Trace Honeycomb API Key",
300+
Usage: "Enables trace exporting to Honeycomb.io using the provided API Key.",
301+
Flag: "trace-honeycomb-api-key",
302+
Secret: true,
303+
},
296304
},
297305
SecureAuthCookie: &codersdk.DeploymentConfigField[bool]{
298306
Name: "Secure Auth Cookie",

cli/deployment/config_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ func TestConfig(t *testing.T) {
114114
require.Equal(t, config.TLS.Enable.Value, true)
115115
require.Equal(t, config.TLS.MinVersion.Value, "tls10")
116116
},
117+
}, {
118+
Name: "Trace",
119+
Env: map[string]string{
120+
"CODER_TRACE_ENABLE": "true",
121+
"CODER_TRACE_HONEYCOMB_API_KEY": "my-honeycomb-key",
122+
},
123+
Valid: func(config *codersdk.DeploymentConfig) {
124+
require.Equal(t, config.Trace.Enable.Value, true)
125+
require.Equal(t, config.Trace.HoneycombAPIKey.Value, "my-honeycomb-key")
126+
},
117127
}, {
118128
Name: "OIDC",
119129
Env: map[string]string{
@@ -192,6 +202,7 @@ func TestConfig(t *testing.T) {
192202
}} {
193203
tc := tc
194204
t.Run(tc.Name, func(t *testing.T) {
205+
t.Helper()
195206
for key, value := range tc.Env {
196207
t.Setenv(key, value)
197208
}

cli/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
125125
shouldCoderTrace = cfg.Telemetry.Trace.Value
126126
}
127127

128-
if cfg.TraceEnable.Value || shouldCoderTrace {
128+
if cfg.Trace.Enable.Value || shouldCoderTrace {
129129
sdkTracerProvider, closeTracing, err := tracing.TracerProvider(ctx, "coderd", tracing.TracerOpts{
130-
Default: cfg.TraceEnable.Value,
130+
Default: cfg.Trace.Enable.Value,
131131
Coder: shouldCoderTrace,
132132
})
133133
if err != nil {

coderd/tracing/exporter.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
sdktrace "go.opentelemetry.io/otel/sdk/trace"
1414
semconv "go.opentelemetry.io/otel/semconv/v1.11.0"
1515
"golang.org/x/xerrors"
16+
"google.golang.org/grpc/credentials"
1617
)
1718

1819
// TracerOpts specifies which telemetry exporters should be configured.
@@ -23,6 +24,8 @@ type TracerOpts struct {
2324
// Coder exports traces to Coder's public tracing ingest service and is used
2425
// to improve the product. It is disabled when opting out of telemetry.
2526
Coder bool
27+
// Exports traces to Honeycomb.io with the provided API key.
28+
Honeycomb string
2629
}
2730

2831
// TracerProvider creates a grpc otlp exporter and configures a trace provider.
@@ -57,6 +60,14 @@ func TracerProvider(ctx context.Context, service string, opts TracerOpts) (*sdkt
5760
closers = append(closers, exporter.Shutdown)
5861
tracerOpts = append(tracerOpts, sdktrace.WithBatcher(exporter))
5962
}
63+
if opts.Honeycomb != "" {
64+
exporter, err := HoneycombExporter(ctx, opts.Honeycomb)
65+
if err != nil {
66+
return nil, nil, xerrors.Errorf("honeycomb exporter: %w", err)
67+
}
68+
closers = append(closers, exporter.Shutdown)
69+
tracerOpts = append(tracerOpts, sdktrace.WithBatcher(exporter))
70+
}
6071

6172
tracerProvider := sdktrace.NewTracerProvider(tracerOpts...)
6273
otel.SetTracerProvider(tracerProvider)
@@ -101,3 +112,20 @@ func CoderExporter(ctx context.Context) (*otlptrace.Exporter, error) {
101112

102113
return exporter, nil
103114
}
115+
116+
func HoneycombExporter(ctx context.Context, apiKey string) (*otlptrace.Exporter, error) {
117+
opts := []otlptracegrpc.Option{
118+
otlptracegrpc.WithEndpoint("api.honeycomb.io:443"),
119+
otlptracegrpc.WithHeaders(map[string]string{
120+
"x-honeycomb-team": apiKey,
121+
}),
122+
otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")),
123+
}
124+
125+
exporter, err := otlptrace.New(ctx, otlptracegrpc.NewClient(opts...))
126+
if err != nil {
127+
return nil, xerrors.Errorf("create otlp exporter: %w", err)
128+
}
129+
130+
return exporter, nil
131+
}

codersdk/deploymentconfig.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type DeploymentConfig struct {
2929
OIDC *OIDCConfig `json:"oidc" typescript:",notnull"`
3030
Telemetry *TelemetryConfig `json:"telemetry" typescript:",notnull"`
3131
TLS *TLSConfig `json:"tls" typescript:",notnull"`
32-
TraceEnable *DeploymentConfigField[bool] `json:"trace_enable" typescript:",notnull"`
32+
Trace *TraceConfig `json:"trace" typescript:",notnull"`
3333
SecureAuthCookie *DeploymentConfigField[bool] `json:"secure_auth_cookie" typescript:",notnull"`
3434
SSHKeygenAlgorithm *DeploymentConfigField[string] `json:"ssh_keygen_algorithm" typescript:",notnull"`
3535
AutoImportTemplates *DeploymentConfigField[[]string] `json:"auto_import_templates" typescript:",notnull"`
@@ -107,6 +107,11 @@ type TLSConfig struct {
107107
MinVersion *DeploymentConfigField[string] `json:"min_version" typescript:",notnull"`
108108
}
109109

110+
type TraceConfig struct {
111+
Enable *DeploymentConfigField[bool] `json:"enable" typescript:",notnull"`
112+
HoneycombAPIKey *DeploymentConfigField[string] `json:"honeycomb_api_key" typescript:",notnull"`
113+
}
114+
110115
type GitAuthConfig struct {
111116
ID string `json:"id"`
112117
Type string `json:"type"`

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ require (
303303
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
304304
google.golang.org/appengine v1.6.7 // indirect
305305
google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de // indirect
306-
google.golang.org/grpc v1.50.1 // indirect
306+
google.golang.org/grpc v1.50.1
307307
gopkg.in/square/go-jose.v2 v2.6.0
308308
gopkg.in/yaml.v2 v2.4.0 // indirect
309309
howett.net/plist v1.0.0 // indirect

site/src/api/typesGenerated.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ export interface DeploymentConfig {
292292
readonly oidc: OIDCConfig
293293
readonly telemetry: TelemetryConfig
294294
readonly tls: TLSConfig
295-
readonly trace_enable: DeploymentConfigField<boolean>
295+
readonly trace: TraceConfig
296296
readonly secure_auth_cookie: DeploymentConfigField<boolean>
297297
readonly ssh_keygen_algorithm: DeploymentConfigField<string>
298298
readonly auto_import_templates: DeploymentConfigField<string[]>
@@ -664,6 +664,12 @@ export interface TemplateVersionsByTemplateRequest extends Pagination {
664664
readonly template_id: string
665665
}
666666

667+
// From codersdk/deploymentconfig.go
668+
export interface TraceConfig {
669+
readonly enable: DeploymentConfigField<boolean>
670+
readonly honeycomb_api_key: DeploymentConfigField<string>
671+
}
672+
667673
// From codersdk/templates.go
668674
export interface UpdateActiveTemplateVersion {
669675
readonly id: string

0 commit comments

Comments
 (0)