package demogrpc import ( "context" "fmt" "github.com/go-resty/resty/v2" "github.com/rs/zerolog" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" grpccodes "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel" pb "gitea.libretechconsulting.com/rmcguire/go-server-with-otel/api/demo/app/v1alpha1" "gitea.libretechconsulting.com/rmcguire/go-server-with-otel/pkg/config" ) const ( defaultFactType = config.TypeRandom factsBaseURI = "https://uselessfacts.jsph.pl/api/v2/facts" ) type DemoGRPCServer struct { tracer trace.Tracer ctx context.Context cfg *config.DemoConfig client *resty.Client pb.UnimplementedDemoAppServiceServer } func NewDemoGRPCServer(ctx context.Context, cfg *config.DemoConfig) *DemoGRPCServer { if cfg.Opts == nil { cfg.Opts = &config.DemoOpts{} } if cfg.Opts.FactType == "" { cfg.Opts.FactType = config.TypeRandom } return &DemoGRPCServer{ ctx: ctx, cfg: cfg, tracer: otel.GetTracer(ctx, "demoGRPCServer"), client: resty.New().SetBaseURL(factsBaseURI), } } func (d *DemoGRPCServer) GetDemo(ctx context.Context, req *pb.GetDemoRequest) ( *pb.GetDemoResponse, error, ) { ctx, span := d.tracer.Start(ctx, "getDemo", trace.WithAttributes( attribute.String("language", req.GetLanguage()), )) defer span.End() r := d.client.R().SetContext(ctx) if req.GetLanguage() != "" { r = r.SetQueryParam("language", req.GetLanguage()) } fact := new(RandomFact) r.SetResult(fact) resp, err := r.Get(fmt.Sprintf("/%s", d.cfg.Opts.FactType)) if err != nil { span.SetStatus(codes.Error, err.Error()) span.RecordError(err) zerolog.Ctx(d.ctx).Err(err).Send() return nil, status.Errorf(grpccodes.Unknown, "%s: %s", err.Error(), string(resp.Body())) } span.SetAttributes(attribute.String("fact", fact.Text)) span.SetStatus(codes.Ok, "") zerolog.Ctx(d.ctx).Debug().Str("fact", fact.Text).Msg("retrieved fact") return fact.FactToProto(), nil }