dagger/dagger · error

failed to create fullTotal metric: %w

Error message

failed to create fullTotal metric: %w

What it means

This error wraps the failure of meter.Int64Gauge when creating the CPU pressure 'fullTotal' gauge (telemetry.CPUStatPressureFullTotal) in newCPUPressureSampler. The OpenTelemetry meter refuses to create the instrument, typically because the instrument name violates OTel naming rules or the meter/provider is misconfigured or shutdown. The sampler cannot be constructed, so NewSampler fails and no CPU pressure metrics are collected.

Source

Thrown at engine/engineutil/resources/cpustat.go:134

		cpuPressureFilePath: filepath.Join(cgroupPath, cpuPressureFile),
		commonAttrs:         commonAttrs,
	}
	var err error

	s.someTotal, err = meter.Int64Gauge(telemetry.CPUStatPressureSomeTotal,
		metric.WithUnit(telemetry.MicrosecondUnitName),
		metric.WithDescription("The total time that any task in the container has been throttled due to CPU pressure"),
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create someTotal metric: %w", err)
	}

	s.fullTotal, err = meter.Int64Gauge(telemetry.CPUStatPressureFullTotal,
		metric.WithUnit(telemetry.MicrosecondUnitName),
		metric.WithDescription("The total time that all tasks in the container have simultaneously been throttled due to CPU pressure"),
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create fullTotal metric: %w", err)
	}

	return s, nil
}

type cpuPressureSample struct {
	someTotal int64GaugeSample
	fullTotal int64GaugeSample
}

func (s *cpuPressureSampler) sample(ctx context.Context) error {
	sample := cpuPressureSample{
		someTotal: newInt64GaugeSample(s.someTotal, s.commonAttrs),
		fullTotal: newInt64GaugeSample(s.fullTotal, s.commonAttrs),
	}

	bs, err := os.ReadFile(s.cpuPressureFilePath)
	switch {

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Verify the OTel MeterProvider is installed and not shut down before NewSampler is called (otel.SetMeterProvider with a working SDK exporter).
  2. Check the wrapped error (%w cause) for instrument-name validation messages; ensure telemetry.CPUStatPressureFullTotal produces a valid OTel instrument name.
  3. Confirm the metric SDK in use supports Int64Gauge (gauge instruments require otel SDK >= v1.19/semconv support); upgrade go.opentelemetry.io/otel if needed.
  4. Add a test that constructs NewSampler with the real MeterProvider to catch registration regressions early.

Example fix

// before
meter := otel.Meter("") // provider never set / already shut down
s, err := resources.NewSampler(ctx, cgroupPath, meter, attrs)
// after
otel.SetMeterProvider(sdkmetric.NewMeterProvider())
meter := otel.Meter("dagger/engine")
s, err := resources.NewSampler(ctx, cgroupPath, meter, attrs)
Defensive patterns

Strategy: try-catch

Validate before calling

if otel.GetMeterProvider() == noop.NewMeterProvider() { return errors.New("no MeterProvider configured before NewSampler") }

Type guard

func isOTelInitErr(err error) bool { return err != nil && strings.Contains(err.Error(), "failed to create") }

Try / catch

sampler, err := resources.NewSampler(ctx, cgroupPath, meter, attrs)
if err != nil {
    log.Warn("resource metrics disabled", "err", err)
    sampler = nil // fall back to running without telemetry
}

Prevention

When it happens

Trigger: Calling NewSampler (which builds newCPUPressureSampler) while the OTel meter fails to instantiate an Int64Gauge named per telemetry.CPUStatPressureFullTotal — e.g. a meter from a shut-down or broken MeterProvider, or an instrument name/invalid configuration rejected by the SDK.

Common situations: Initializing the resource sampler before otel.SetMeterProvider or after the provider was shut down; using a no-op/global meter with an SDK that enforces instrument-name conventions; duplicate instrument registration conflicts in custom SDK builds.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/25cc3495dd6fe47e. Report an issue: GitHub.