Files
grpc-toolkit/otel/dsn.go
2025-06-05 16:31:03 +02:00

104 lines
1.9 KiB
Go

package otel
import (
"encoding/base64"
"fmt"
"net"
"net/url"
)
type DSN struct {
original string
Scheme string
Host string
HTTPPort string
User string
Password string
Token string
}
func (dsn *DSN) String() string {
return dsn.original
}
func (dsn *DSN) SiteURL() string {
return dsn.Scheme + "://" + joinHostPort(dsn.Host, dsn.HTTPPort)
}
func (dsn *DSN) OTLPHttpEndpoint() string {
return joinHostPort(dsn.Host, dsn.HTTPPort)
}
func (dsn *DSN) Headers() map[string]string {
if dsn.Token != "" {
return map[string]string{
"Authorization": "Bearer " + dsn.Token,
}
}
if dsn.User != "" && dsn.Password != "" {
return map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte(dsn.User+":"+dsn.Password)),
}
}
return nil
}
func ParseDSN(dsnStr string) (*DSN, error) {
if dsnStr == "" {
return nil, fmt.Errorf("DSN is empty (use WithDSN or OTEL_DSN env var)")
}
u, err := url.Parse(dsnStr)
if err != nil {
return nil, fmt.Errorf("can't parse DSN=%q: %s", dsnStr, err)
}
switch u.Scheme {
case "http", "https":
case "":
return nil, fmt.Errorf("DSN=%q does not have a scheme", dsnStr)
default:
return nil, fmt.Errorf("DSN=%q has unsupported scheme %q", dsnStr, u.Scheme)
}
if u.Host == "" {
return nil, fmt.Errorf("DSN=%q does not have a host", dsnStr)
}
dsn := DSN{
original: dsnStr,
Scheme: u.Scheme,
Host: u.Host,
}
if p, ok := u.User.Password(); ok {
dsn.User = u.User.Username()
dsn.Password = p
} else {
dsn.Token = u.User.Username()
}
if host, port, err := net.SplitHostPort(u.Host); err == nil {
dsn.Host = host
dsn.HTTPPort = port
}
if dsn.HTTPPort == "" {
switch dsn.Scheme {
case "http":
dsn.HTTPPort = "80"
case "https":
dsn.HTTPPort = "443"
}
}
return &dsn, nil
}
func joinHostPort(host, port string) string {
if port == "" {
return host
}
return net.JoinHostPort(host, port)
}