rework list courses page to be flatten
This commit is contained in:
@ -29,7 +29,13 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
const savingOrganizationIDInternalInsteadOfExternal = false
|
||||
|
||||
func app(ctx context.Context) error {
|
||||
if !savingOrganizationIDInternalInsteadOfExternal {
|
||||
panic("fix saving ogranization id as external id instead of internal")
|
||||
}
|
||||
|
||||
var cfgpath string
|
||||
if len(os.Args) > 1 {
|
||||
cfgpath = os.Args[1]
|
||||
|
||||
@ -107,11 +107,21 @@ func middlewareCustomWriterInjector() mux.MiddlewareFunc {
|
||||
}
|
||||
}
|
||||
|
||||
type attributeStringKey string
|
||||
|
||||
func (k attributeStringKey) Value(value string) attribute.KeyValue {
|
||||
return attribute.String(string(k), value)
|
||||
}
|
||||
|
||||
func middlewareTrace() mux.MiddlewareFunc {
|
||||
reqidAttr := attribute.Key("http.request_id")
|
||||
statusAttr := attribute.Key("http.status_code")
|
||||
payloadAttr := attribute.Key("http.payload_size")
|
||||
pathAttr := attribute.Key("http.template_path")
|
||||
methodAttr := attributeStringKey("http.request.method")
|
||||
reqidAttr := attributeStringKey("http.request_id")
|
||||
routeAttr := attributeStringKey("http.route")
|
||||
queryAttr := attributeStringKey("url.query")
|
||||
pathAttr := attributeStringKey("http.path")
|
||||
uaAttr := attributeStringKey("user_agent.original")
|
||||
statusAttr := attribute.Key("http.response.status_code")
|
||||
payloadAttr := attribute.Key("http.response_content_length")
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -120,14 +130,18 @@ func middlewareTrace() mux.MiddlewareFunc {
|
||||
|
||||
var span trace.Span
|
||||
route := mux.CurrentRoute(r)
|
||||
hname := route.GetName()
|
||||
hpath, _ := route.GetPathTemplate()
|
||||
ctx, span = webtracer.Start(
|
||||
ctx, "http."+hname,
|
||||
ctx, r.Method+" "+hpath,
|
||||
trace.WithAttributes(
|
||||
reqidAttr.String(reqid),
|
||||
pathAttr.String(hpath),
|
||||
methodAttr.Value(r.Method),
|
||||
reqidAttr.Value(reqid),
|
||||
routeAttr.Value(hpath),
|
||||
pathAttr.Value(r.URL.Path),
|
||||
queryAttr.Value(r.URL.RawQuery),
|
||||
uaAttr.Value(r.UserAgent()),
|
||||
),
|
||||
trace.WithSpanKind(trace.SpanKindServer),
|
||||
)
|
||||
defer span.End()
|
||||
|
||||
|
||||
@ -8,18 +8,19 @@ import (
|
||||
"time"
|
||||
|
||||
"git.loyso.art/frx/kurious/internal/common/config"
|
||||
"git.loyso.art/frx/kurious/pkg/xdefault"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
|
||||
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
|
||||
)
|
||||
|
||||
var webtracer = otel.Tracer("kuriweb.http")
|
||||
@ -46,19 +47,26 @@ func setupOtelSDK(ctx context.Context, cfg config.Trace) (shutdown shutdownFunc,
|
||||
prop := newPropagator()
|
||||
otel.SetTextMapPropagator(prop)
|
||||
|
||||
tracerProvider, err := newTraceProvider(ctx, cfg.Endpoint, cfg.LicenseKey)
|
||||
tracerProvider, err := newCommonTraceProvider(ctx, TraceProviderParams{
|
||||
Endpoint: cfg.Endpoint,
|
||||
Type: cfg.Type,
|
||||
AuthHeader: cfg.APIHeader,
|
||||
APIKey: cfg.APIKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, handleError(err)
|
||||
}
|
||||
shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown)
|
||||
otel.SetTracerProvider(tracerProvider)
|
||||
|
||||
meterProvider, err := newMeterProvider()
|
||||
if err != nil {
|
||||
return nil, handleError(err)
|
||||
if cfg.ShowMetrics {
|
||||
meterProvider, err := newMeterProvider()
|
||||
if err != nil {
|
||||
return nil, handleError(err)
|
||||
}
|
||||
shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown)
|
||||
otel.SetMeterProvider(meterProvider)
|
||||
}
|
||||
shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown)
|
||||
otel.SetMeterProvider(meterProvider)
|
||||
|
||||
return shutdown, nil
|
||||
}
|
||||
@ -70,46 +78,75 @@ func newPropagator() propagation.TextMapPropagator {
|
||||
)
|
||||
}
|
||||
|
||||
const defaultNewRelicEndpoint = "otlp.eu01.nr-data.net:443"
|
||||
type TraceProviderParams struct {
|
||||
Type config.TraceClientType
|
||||
Endpoint string
|
||||
APIKey string
|
||||
AuthHeader string
|
||||
}
|
||||
|
||||
func newTraceProvider(ctx context.Context, endpoint, licensekey string) (traceProvider *trace.TracerProvider, err error) {
|
||||
opts := make([]trace.TracerProviderOption, 0, 2)
|
||||
func newCommonTraceProvider(ctx context.Context, params TraceProviderParams) (tp *trace.TracerProvider, err error) {
|
||||
r, err := resource.New(
|
||||
ctx,
|
||||
resource.WithDetectors(
|
||||
resource.StringDetector(semconv.SchemaURL, semconv.ServiceNameKey, func() (string, error) {
|
||||
return "bigstats:kuriweb", nil
|
||||
}),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("making new resource: %w", err)
|
||||
}
|
||||
|
||||
r, err = resource.Merge(resource.Default(), r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("merging resources: %w", err)
|
||||
}
|
||||
|
||||
opts := make([]trace.TracerProviderOption, 0, 4)
|
||||
opts = append(
|
||||
opts,
|
||||
trace.WithSampler(trace.AlwaysSample()),
|
||||
trace.WithResource(resource.Default()),
|
||||
trace.WithResource(r),
|
||||
)
|
||||
|
||||
if licensekey != "" {
|
||||
endpoint = xdefault.WithFallback(endpoint, defaultNewRelicEndpoint)
|
||||
client, err := otlptracegrpc.New(
|
||||
ctx,
|
||||
otlptracegrpc.WithEndpoint(endpoint),
|
||||
otlptracegrpc.WithHeaders(map[string]string{
|
||||
"api-key": licensekey,
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("making grpc client: %w", err)
|
||||
if params.Type != config.TraceClientTypeUnset {
|
||||
var spanExporter trace.SpanExporter
|
||||
var headers map[string]string
|
||||
|
||||
if params.AuthHeader != "" {
|
||||
headers = make(map[string]string, 1)
|
||||
headers[params.AuthHeader] = params.APIKey
|
||||
}
|
||||
|
||||
opts = append(opts, trace.WithBatcher(client, trace.WithBatchTimeout(time.Second*10)))
|
||||
} else {
|
||||
traceExporter, err := stdouttrace.New(
|
||||
stdouttrace.WithPrettyPrint())
|
||||
switch params.Type {
|
||||
case config.TraceClientTypeGRPC:
|
||||
spanExporter, err = otlptracegrpc.New(
|
||||
ctx,
|
||||
otlptracegrpc.WithEndpointURL(params.Endpoint),
|
||||
otlptracegrpc.WithHeaders(headers),
|
||||
)
|
||||
case config.TraceClientTypeHTTP:
|
||||
httpClient := otlptracehttp.NewClient(
|
||||
otlptracehttp.WithEndpointURL(params.Endpoint),
|
||||
otlptracehttp.WithHeaders(headers),
|
||||
)
|
||||
spanExporter, err = otlptrace.New(ctx, httpClient)
|
||||
case config.TraceClientTypeStdout:
|
||||
spanExporter, err = stdouttrace.New(stdouttrace.WithPrettyPrint())
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported provider type")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("making trace exporter: %w", err)
|
||||
}
|
||||
|
||||
opts = append(
|
||||
opts,
|
||||
trace.WithBatcher(traceExporter, trace.WithBatchTimeout(time.Second*5)),
|
||||
)
|
||||
opts = append(opts, trace.WithBatcher(spanExporter))
|
||||
}
|
||||
|
||||
traceProvider = trace.NewTracerProvider(opts...)
|
||||
tp = trace.NewTracerProvider(opts...)
|
||||
|
||||
return traceProvider, nil
|
||||
return tp, nil
|
||||
}
|
||||
|
||||
func newMeterProvider() (*metric.MeterProvider, error) {
|
||||
@ -127,6 +164,6 @@ func newMeterProvider() (*metric.MeterProvider, error) {
|
||||
}
|
||||
|
||||
func muxHandleFunc(router *mux.Router, name, path string, hf http.HandlerFunc) *mux.Route {
|
||||
h := otelhttp.WithRouteTag(path, hf)
|
||||
return router.Handle(path, h).Name(name)
|
||||
// h := otelhttp.WithRouteTag(path, hf)
|
||||
return router.Handle(path, hf).Name(name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user