From b467d0fa36f9720038bf5714d7ce1409a375d2a8 Mon Sep 17 00:00:00 2001 From: Brian Ginsburg <7957636+bgins@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:01:18 -0700 Subject: [PATCH] feat: Add job creator tracer (#411) * chore: Add telemetry options * feat: Add onchain job-creator tracer * feat: Add run job-creator tracer * chore: Add integration test noop tracer * chore: Remove comment We can read the yacspin docs: https://github.com/theckman/yacspin * chore: Disable telemetry in CI * fix: Process onchain telemetry options --- .github/workflows/test.yml | 3 ++- cmd/lilypad/jobcreator.go | 18 ++++++++++++------ cmd/lilypad/run.go | 27 ++++++++++++--------------- pkg/jobcreator/controller.go | 4 ++++ pkg/jobcreator/jobcreator.go | 5 ++++- pkg/jobcreator/onchain_jobcreator.go | 4 +++- pkg/jobcreator/run.go | 8 ++++---- pkg/options/job-creator.go | 22 ++++++++++++++++++++++ test/integration_test.go | 3 ++- 9 files changed, 65 insertions(+), 29 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9515526f..cf0d8446 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: - name: Run unit tests run: ./stack unit-tests - + run-integration-tests: runs-on: ubuntu-latest steps: @@ -50,6 +50,7 @@ jobs: - name: Run tests env: LOG_LEVEL: debug + DISABLE_TELEMETRY: true run: ./stack integration-tests - name: Display resource provider logs diff --git a/cmd/lilypad/jobcreator.go b/cmd/lilypad/jobcreator.go index 1affab81..ee5a92a0 100644 --- a/cmd/lilypad/jobcreator.go +++ b/cmd/lilypad/jobcreator.go @@ -5,8 +5,8 @@ import ( optionsfactory "github.com/lilypad-tech/lilypad/pkg/options" "github.com/lilypad-tech/lilypad/pkg/system" "github.com/lilypad-tech/lilypad/pkg/web3" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" - "go.opentelemetry.io/otel/trace/noop" ) func newJobCreatorCmd() *cobra.Command { @@ -24,7 +24,7 @@ func newJobCreatorCmd() *cobra.Command { if err != nil { return err } - return runJobCreator(cmd, options) + return runJobCreator(cmd, options, network) }, } @@ -33,18 +33,24 @@ func newJobCreatorCmd() *cobra.Command { return solverCmd } -func runJobCreator(cmd *cobra.Command, options jobcreator.JobCreatorOptions) error { +func runJobCreator(cmd *cobra.Command, options jobcreator.JobCreatorOptions, network string) error { commandCtx := system.NewCommandContext(cmd) defer commandCtx.Cleanup() - noopTracer := noop.NewTracerProvider().Tracer(system.GetOTelServiceName(system.JobCreatorService)) - web3SDK, err := web3.NewContractSDK(commandCtx.Ctx, options.Web3, noopTracer) + telemetry, err := configureTelemetry(commandCtx.Ctx, system.JobCreatorService, network, options.Telemetry, options.Web3) + if err != nil { + log.Warn().Msgf("failed to setup opentelemetry: %s", err) + } + commandCtx.Cm.RegisterCallbackWithContext(telemetry.Shutdown) + tracer := telemetry.TracerProvider.Tracer(system.GetOTelServiceName(system.JobCreatorService)) + + web3SDK, err := web3.NewContractSDK(commandCtx.Ctx, options.Web3, tracer) if err != nil { return err } // create the job creator and start it's control loop - jobCreatorService, err := jobcreator.NewOnChainJobCreator(options, web3SDK) + jobCreatorService, err := jobcreator.NewOnChainJobCreator(options, web3SDK, tracer) if err != nil { return err } diff --git a/cmd/lilypad/run.go b/cmd/lilypad/run.go index 9e9e62a4..2cc3cd2b 100644 --- a/cmd/lilypad/run.go +++ b/cmd/lilypad/run.go @@ -14,6 +14,7 @@ import ( optionsfactory "github.com/lilypad-tech/lilypad/pkg/options" "github.com/lilypad-tech/lilypad/pkg/solver" "github.com/lilypad-tech/lilypad/pkg/system" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" "github.com/theckman/yacspin" @@ -33,7 +34,7 @@ func newRunCmd() *cobra.Command { if err != nil { return err } - return runJob(cmd, options) + return runJob(cmd, options, network) }, } @@ -42,7 +43,7 @@ func newRunCmd() *cobra.Command { return runCmd } -func runJob(cmd *cobra.Command, options jobcreator.JobCreatorOptions) error { +func runJob(cmd *cobra.Command, options jobcreator.JobCreatorOptions, network string) error { c := color.New(color.FgCyan).Add(color.Bold) header := ` ⠀⠀⠀⠀⠀⠀⣀⣤⣤⢠⣤⣀⠀⠀⠀⠀⠀ @@ -72,18 +73,6 @@ func runJob(cmd *cobra.Command, options jobcreator.JobCreatorOptions) error { return fmt.Errorf("failed to start spinner: %w", err) } - // update message - // spinner.Message("uploading files") - - // let spinner render some more - // time.Sleep(1 * time.Second) - - // if you wanted to print a failure message... - // - // if err := spinner.StopFail(); err != nil { - // return fmt.Errorf("failed to stop spinner: %w", err) - // } - if err := spinner.Stop(); err != nil { return fmt.Errorf("failed to stop spinner: %w", err) } @@ -95,7 +84,15 @@ func runJob(cmd *cobra.Command, options jobcreator.JobCreatorOptions) error { commandCtx := system.NewCommandContext(cmd) defer commandCtx.Cleanup() - result, err := jobcreator.RunJob(commandCtx, options, func(evOffer data.JobOfferContainer) { + + telemetry, err := configureTelemetry(commandCtx.Ctx, system.JobCreatorService, network, options.Telemetry, options.Web3) + if err != nil { + log.Warn().Msgf("failed to setup opentelemetry: %s", err) + } + commandCtx.Cm.RegisterCallbackWithContext(telemetry.Shutdown) + tracer := telemetry.TracerProvider.Tracer(system.GetOTelServiceName(system.JobCreatorService)) + + result, err := jobcreator.RunJob(commandCtx, options, tracer, func(evOffer data.JobOfferContainer) { spinner.Stop() st := data.GetAgreementStateString(evOffer.State) var desc string diff --git a/pkg/jobcreator/controller.go b/pkg/jobcreator/controller.go index c711524a..8cb3e846 100644 --- a/pkg/jobcreator/controller.go +++ b/pkg/jobcreator/controller.go @@ -13,6 +13,7 @@ import ( "github.com/lilypad-tech/lilypad/pkg/system" "github.com/lilypad-tech/lilypad/pkg/web3" "github.com/lilypad-tech/lilypad/pkg/web3/bindings/storage" + "go.opentelemetry.io/otel/trace" ) type JobOfferSubscriber func(offer data.JobOfferContainer) @@ -25,6 +26,7 @@ type JobCreatorController struct { loop *system.ControlLoop log *system.ServiceLogger jobOfferSubscriptions []JobOfferSubscriber + tracer trace.Tracer } // the background "even if we have not heard of an event" loop @@ -36,6 +38,7 @@ const CONTROL_LOOP_INTERVAL = 10 * time.Second func NewJobCreatorController( options JobCreatorOptions, web3SDK *web3.Web3SDK, + tracer trace.Tracer, ) (*JobCreatorController, error) { // we know the address of the solver but what is it's url? solverUrl, err := web3SDK.GetSolverUrl(options.Offer.Services.Solver) @@ -63,6 +66,7 @@ func NewJobCreatorController( web3Events: web3.NewEventChannels(), log: system.NewServiceLogger(system.JobCreatorService), jobOfferSubscriptions: []JobOfferSubscriber{}, + tracer: tracer, } return controller, nil } diff --git a/pkg/jobcreator/jobcreator.go b/pkg/jobcreator/jobcreator.go index 984af3f8..94354880 100644 --- a/pkg/jobcreator/jobcreator.go +++ b/pkg/jobcreator/jobcreator.go @@ -6,6 +6,7 @@ import ( "github.com/lilypad-tech/lilypad/pkg/data" "github.com/lilypad-tech/lilypad/pkg/system" "github.com/lilypad-tech/lilypad/pkg/web3" + "go.opentelemetry.io/otel/trace" ) type JobCreatorMediationOptions struct { @@ -39,6 +40,7 @@ type JobCreatorOptions struct { Mediation JobCreatorMediationOptions Offer JobCreatorOfferOptions Web3 web3.Web3Options + Telemetry system.TelemetryOptions } type JobCreator struct { @@ -50,8 +52,9 @@ type JobCreator struct { func NewJobCreator( options JobCreatorOptions, web3SDK *web3.Web3SDK, + tracer trace.Tracer, ) (*JobCreator, error) { - controller, err := NewJobCreatorController(options, web3SDK) + controller, err := NewJobCreatorController(options, web3SDK, tracer) if err != nil { return nil, err } diff --git a/pkg/jobcreator/onchain_jobcreator.go b/pkg/jobcreator/onchain_jobcreator.go index fd930bae..6b3c49c5 100644 --- a/pkg/jobcreator/onchain_jobcreator.go +++ b/pkg/jobcreator/onchain_jobcreator.go @@ -11,6 +11,7 @@ import ( "github.com/lilypad-tech/lilypad/pkg/system" "github.com/lilypad-tech/lilypad/pkg/web3" jobcreatorweb3 "github.com/lilypad-tech/lilypad/pkg/web3/bindings/jobcreator" + "go.opentelemetry.io/otel/trace" ) const JOB_PRICE = 2 @@ -26,8 +27,9 @@ type OnChainJobCreator struct { func NewOnChainJobCreator( options JobCreatorOptions, web3SDK *web3.Web3SDK, + tracer trace.Tracer, ) (*OnChainJobCreator, error) { - controller, err := NewJobCreatorController(options, web3SDK) + controller, err := NewJobCreatorController(options, web3SDK, tracer) if err != nil { return nil, err } diff --git a/pkg/jobcreator/run.go b/pkg/jobcreator/run.go index 3e2920fe..db762d57 100644 --- a/pkg/jobcreator/run.go +++ b/pkg/jobcreator/run.go @@ -7,7 +7,7 @@ import ( "github.com/lilypad-tech/lilypad/pkg/data" "github.com/lilypad-tech/lilypad/pkg/system" "github.com/lilypad-tech/lilypad/pkg/web3" - "go.opentelemetry.io/otel/trace/noop" + "go.opentelemetry.io/otel/trace" ) type RunJobResults struct { @@ -18,16 +18,16 @@ type RunJobResults struct { func RunJob( ctx *system.CommandContext, options JobCreatorOptions, + tracer trace.Tracer, eventSub JobOfferSubscriber, ) (*RunJobResults, error) { - noopTracer := noop.NewTracerProvider().Tracer(system.GetOTelServiceName(system.JobCreatorService)) - web3SDK, err := web3.NewContractSDK(ctx.Ctx, options.Web3, noopTracer) + web3SDK, err := web3.NewContractSDK(ctx.Ctx, options.Web3, tracer) if err != nil { return nil, err } // create the job creator and start it's control loop - jobCreatorService, err := NewJobCreator(options, web3SDK) + jobCreatorService, err := NewJobCreator(options, web3SDK, tracer) if err != nil { return nil, err } diff --git a/pkg/options/job-creator.go b/pkg/options/job-creator.go index 78382bcf..86c5bc65 100644 --- a/pkg/options/job-creator.go +++ b/pkg/options/job-creator.go @@ -14,6 +14,7 @@ func NewJobCreatorOptions() jobcreator.JobCreatorOptions { Offer: GetDefaultJobCreatorOfferOptions(), Web3: GetDefaultWeb3Options(), Mediation: GetDefaultJobCreatorMediationOptions(), + Telemetry: GetDefaultTelemetryOptions(), } options.Web3.Service = system.JobCreatorService return options @@ -62,6 +63,7 @@ func AddJobCreatorCliFlags(cmd *cobra.Command, options *jobcreator.JobCreatorOpt AddJobCreatorMediationCliFlags(cmd, &options.Mediation) AddWeb3CliFlags(cmd, &options.Web3) AddJobCreatorOfferCliFlags(cmd, &options.Offer) + AddTelemetryCliFlags(cmd, &options.Telemetry) } func CheckJobCreatorOptions(options jobcreator.JobCreatorOptions) error { @@ -77,6 +79,10 @@ func CheckJobCreatorOptions(options jobcreator.JobCreatorOptions) error { if err != nil { return err } + err = CheckTelemetryOptions(options.Telemetry) + if err != nil { + return err + } if options.Mediation.CheckResultsPercentage < 0 || options.Mediation.CheckResultsPercentage > 100 { return fmt.Errorf("mediation-chance must be between 0 and 100") @@ -119,6 +125,12 @@ func ProcessJobCreatorOptions(options jobcreator.JobCreatorOptions, args []strin } options.Offer.Target = newTargetOptions + newTelemetryOptions, err := ProcessTelemetryOptions(options.Telemetry, network) + if err != nil { + return options, err + } + options.Telemetry = newTelemetryOptions + return options, CheckJobCreatorOptions(options) } @@ -135,6 +147,12 @@ func ProcessOnChainJobCreatorOptions(options jobcreator.JobCreatorOptions, args } options.Offer.Services = newServicesOptions + newTelemetryOptions, err := ProcessTelemetryOptions(options.Telemetry, network) + if err != nil { + return options, err + } + options.Telemetry = newTelemetryOptions + err = CheckWeb3Options(options.Web3) if err != nil { return options, err @@ -143,6 +161,10 @@ func ProcessOnChainJobCreatorOptions(options jobcreator.JobCreatorOptions, args if err != nil { return options, err } + err = CheckTelemetryOptions(options.Telemetry) + if err != nil { + return options, err + } options.Mediation.CheckResultsPercentage = 0 diff --git a/test/integration_test.go b/test/integration_test.go index 5aa79f3f..286ea6f9 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -95,7 +95,8 @@ func testStackWithOptions( return nil, err } - result, err := jobcreator.RunJob(commandCtx, jobCreatorOptions, func(evOffer data.JobOfferContainer) { + noopTracer := traceNoop.NewTracerProvider().Tracer(system.GetOTelServiceName(system.DefaultService)) + result, err := jobcreator.RunJob(commandCtx, jobCreatorOptions, noopTracer, func(evOffer data.JobOfferContainer) { }) if err != nil {