- Add bootstrap package to initialize application components including logger, tracer, and HTTP server. - Create config package to load runtime settings from environment variables. - Implement observability features including logging, metrics, and tracing. - Add health check and hello use cases with corresponding HTTP handlers. - Introduce middleware for request ID, access logging, metrics, and recovery. - Set up HTTP router with defined routes for health and hello endpoints. - Include tests for health and hello endpoints to ensure proper functionality. - Add OpenTelemetry collector configuration for trace exporting.
56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/codes"
|
|
"go.opentelemetry.io/otel/propagation"
|
|
"go.opentelemetry.io/otel/trace"
|
|
)
|
|
|
|
func Tracing(tracer trace.Tracer) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
ctx := otel.GetTextMapPropagator().Extract(c.Request.Context(), propagation.HeaderCarrier(c.Request.Header))
|
|
spanName := fmt.Sprintf("%s %s", c.Request.Method, c.Request.URL.Path)
|
|
|
|
ctx, span := tracer.Start(
|
|
ctx,
|
|
spanName,
|
|
trace.WithSpanKind(trace.SpanKindServer),
|
|
trace.WithAttributes(
|
|
attribute.String("http.request.method", c.Request.Method),
|
|
),
|
|
)
|
|
defer span.End()
|
|
|
|
c.Request = c.Request.WithContext(ctx)
|
|
c.Next()
|
|
|
|
route := c.FullPath()
|
|
if route == "" {
|
|
route = "/unknown"
|
|
}
|
|
|
|
status := c.Writer.Status()
|
|
span.SetName(fmt.Sprintf("%s %s", c.Request.Method, route))
|
|
span.SetAttributes(
|
|
attribute.String("http.route", route),
|
|
attribute.Int("http.response.status_code", status),
|
|
)
|
|
|
|
if status >= http.StatusInternalServerError {
|
|
span.SetStatus(codes.Error, http.StatusText(status))
|
|
}
|
|
if len(c.Errors) > 0 {
|
|
for _, err := range c.Errors {
|
|
span.RecordError(err)
|
|
}
|
|
span.SetStatus(codes.Error, c.Errors.String())
|
|
}
|
|
}
|
|
}
|