Skip to content

feat: add option for exporting traces to a provided Honeycomb team #4816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 12 additions & 4 deletions cli/deployment/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,18 @@ func newConfig() *codersdk.DeploymentConfig {
Default: "tls12",
},
},
TraceEnable: &codersdk.DeploymentConfigField[bool]{
Name: "Trace Enable",
Usage: "Whether application tracing data is collected.",
Flag: "trace",
Trace: &codersdk.TraceConfig{
Enable: &codersdk.DeploymentConfigField[bool]{
Name: "Trace Enable",
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",
Flag: "trace",
},
HoneycombAPIKey: &codersdk.DeploymentConfigField[string]{
Name: "Trace Honeycomb API Key",
Usage: "Enables trace exporting to Honeycomb.io using the provided API Key.",
Flag: "trace-honeycomb-api-key",
Secret: true,
},
},
SecureAuthCookie: &codersdk.DeploymentConfigField[bool]{
Name: "Secure Auth Cookie",
Expand Down
11 changes: 11 additions & 0 deletions cli/deployment/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ func TestConfig(t *testing.T) {
require.Equal(t, config.TLS.Enable.Value, true)
require.Equal(t, config.TLS.MinVersion.Value, "tls10")
},
}, {
Name: "Trace",
Env: map[string]string{
"CODER_TRACE_ENABLE": "true",
"CODER_TRACE_HONEYCOMB_API_KEY": "my-honeycomb-key",
},
Valid: func(config *codersdk.DeploymentConfig) {
require.Equal(t, config.Trace.Enable.Value, true)
require.Equal(t, config.Trace.HoneycombAPIKey.Value, "my-honeycomb-key")
},
}, {
Name: "OIDC",
Env: map[string]string{
Expand Down Expand Up @@ -192,6 +202,7 @@ func TestConfig(t *testing.T) {
}} {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
t.Helper()
for key, value := range tc.Env {
t.Setenv(key, value)
}
Expand Down
4 changes: 2 additions & 2 deletions cli/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
shouldCoderTrace = cfg.Telemetry.Trace.Value
}

if cfg.TraceEnable.Value || shouldCoderTrace {
if cfg.Trace.Enable.Value || shouldCoderTrace {
sdkTracerProvider, closeTracing, err := tracing.TracerProvider(ctx, "coderd", tracing.TracerOpts{
Default: cfg.TraceEnable.Value,
Default: cfg.Trace.Enable.Value,
Coder: shouldCoderTrace,
})
if err != nil {
Expand Down
28 changes: 28 additions & 0 deletions coderd/tracing/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.11.0"
"golang.org/x/xerrors"
"google.golang.org/grpc/credentials"
)

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

// TracerProvider creates a grpc otlp exporter and configures a trace provider.
Expand Down Expand Up @@ -57,6 +60,14 @@ func TracerProvider(ctx context.Context, service string, opts TracerOpts) (*sdkt
closers = append(closers, exporter.Shutdown)
tracerOpts = append(tracerOpts, sdktrace.WithBatcher(exporter))
}
if opts.Honeycomb != "" {
exporter, err := HoneycombExporter(ctx, opts.Honeycomb)
if err != nil {
return nil, nil, xerrors.Errorf("honeycomb exporter: %w", err)
}
closers = append(closers, exporter.Shutdown)
tracerOpts = append(tracerOpts, sdktrace.WithBatcher(exporter))
}

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

return exporter, nil
}

func HoneycombExporter(ctx context.Context, apiKey string) (*otlptrace.Exporter, error) {
opts := []otlptracegrpc.Option{
otlptracegrpc.WithEndpoint("api.honeycomb.io:443"),
otlptracegrpc.WithHeaders(map[string]string{
"x-honeycomb-team": apiKey,
}),
otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")),
}

exporter, err := otlptrace.New(ctx, otlptracegrpc.NewClient(opts...))
if err != nil {
return nil, xerrors.Errorf("create otlp exporter: %w", err)
}

return exporter, nil
}
7 changes: 6 additions & 1 deletion codersdk/deploymentconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type DeploymentConfig struct {
OIDC *OIDCConfig `json:"oidc" typescript:",notnull"`
Telemetry *TelemetryConfig `json:"telemetry" typescript:",notnull"`
TLS *TLSConfig `json:"tls" typescript:",notnull"`
TraceEnable *DeploymentConfigField[bool] `json:"trace_enable" typescript:",notnull"`
Trace *TraceConfig `json:"trace" typescript:",notnull"`
SecureAuthCookie *DeploymentConfigField[bool] `json:"secure_auth_cookie" typescript:",notnull"`
SSHKeygenAlgorithm *DeploymentConfigField[string] `json:"ssh_keygen_algorithm" typescript:",notnull"`
AutoImportTemplates *DeploymentConfigField[[]string] `json:"auto_import_templates" typescript:",notnull"`
Expand Down Expand Up @@ -107,6 +107,11 @@ type TLSConfig struct {
MinVersion *DeploymentConfigField[string] `json:"min_version" typescript:",notnull"`
}

type TraceConfig struct {
Enable *DeploymentConfigField[bool] `json:"enable" typescript:",notnull"`
HoneycombAPIKey *DeploymentConfigField[string] `json:"honeycomb_api_key" typescript:",notnull"`
}

type GitAuthConfig struct {
ID string `json:"id"`
Type string `json:"type"`
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ require (
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de // indirect
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/grpc v1.50.1
gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v2 v2.4.0 // indirect
howett.net/plist v1.0.0 // indirect
Expand Down
8 changes: 7 additions & 1 deletion site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export interface DeploymentConfig {
readonly oidc: OIDCConfig
readonly telemetry: TelemetryConfig
readonly tls: TLSConfig
readonly trace_enable: DeploymentConfigField<boolean>
readonly trace: TraceConfig
readonly secure_auth_cookie: DeploymentConfigField<boolean>
readonly ssh_keygen_algorithm: DeploymentConfigField<string>
readonly auto_import_templates: DeploymentConfigField<string[]>
Expand Down Expand Up @@ -664,6 +664,12 @@ export interface TemplateVersionsByTemplateRequest extends Pagination {
readonly template_id: string
}

// From codersdk/deploymentconfig.go
export interface TraceConfig {
readonly enable: DeploymentConfigField<boolean>
readonly honeycomb_api_key: DeploymentConfigField<string>
}

// From codersdk/templates.go
export interface UpdateActiveTemplateVersion {
readonly id: string
Expand Down