package api import ( "context" "errors" "time" "connectrpc.com/connect" "github.com/mattn/go-sqlite3" "github.com/tigorlazuardi/bluemage/go/gen/models" "github.com/tigorlazuardi/bluemage/go/pkg/errs" "github.com/tigorlazuardi/bluemage/go/pkg/log" "github.com/tigorlazuardi/bluemage/go/pkg/telemetry" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) var ( deviceCreatedCounter, _ = meter.Int64Counter("devices.created", metric.WithDescription("The number of devices have created."), ) deviceCreatedHistogram, _ = meter.Int64Histogram( "devices.creating.duration", metric.WithDescription("The duration for creating devices."), metric.WithUnit("ms"), ) ) func (api *API) DevicesCreate(ctx context.Context, params *models.DeviceSetter) (device *models.Device, err error) { ctx, span := tracer.Start(ctx, "DevicesCreate") defer func() { telemetry.EndWithStatus(span, err) }() start := time.Now() ctx, coll := log.WithQueryCollector(ctx) api.lockf(func() { device, err = models.Devices.Insert(ctx, api.Executor, params) }) if err != nil { if sqliteErr := new(sqlite3.Error); errors.As(err, sqliteErr) { if sqliteErr.Code == sqlite3.ErrConstraint { return nil, errs. Wrapw(sqliteErr, "device already exists", "params", params, "query", coll). Code(connect.CodeAlreadyExists) } } return nil, errs. Wrapw(err, "failed to create device", "params", params, "query", coll, ) } dur := time.Since(start) deviceCreatedCounter.Add(ctx, 1, metric.WithAttributes( attribute.String("slug", params.Slug.GetOrZero()), )) deviceCreatedHistogram.Record(ctx, dur.Milliseconds()) return device, nil }