{"record":{"id":"f2621f96815347fd","repo":"crowdsecurity/crowdsec","slug":"getting-bouncer-usage-metrics-by-name-s-w","errorCode":null,"errorMessage":"getting bouncer usage metrics by name %s: %w","messagePattern":"getting bouncer usage metrics by name (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/metrics.go","lineNumber":58,"sourceCode":"\tif err != nil {\n\t\tc.Log.Warningf(\"GetLPUsageMetricsByOrigin: %s\", err)\n\t\treturn nil, fmt.Errorf(\"getting LP usage metrics by origin %s: %w\", machineId, err)\n\t}\n\n\treturn metrics, nil\n}\n\nfunc (c *Client) GetBouncerUsageMetricsByName(ctx context.Context, bouncerName string) ([]*ent.Metric, error) {\n\tmetrics, err := c.Ent.Metric.Query().\n\t\tWhere(\n\t\t\tmetric.GeneratedTypeEQ(metric.GeneratedTypeRC),\n\t\t\tmetric.GeneratedByEQ(bouncerName),\n\t\t\tmetric.PushedAtIsNil(),\n\t\t).\n\t\tAll(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"GetBouncerUsageMetricsByName: %s\", err)\n\t\treturn nil, fmt.Errorf(\"getting bouncer usage metrics by name %s: %w\", bouncerName, err)\n\t}\n\n\treturn metrics, nil\n}\n\nfunc (c *Client) MarkUsageMetricsAsSent(ctx context.Context, ids []int) error {\n\t_, err := c.Ent.Metric.Update().\n\t\tWhere(metric.IDIn(ids...)).\n\t\tSetPushedAt(time.Now().UTC()).\n\t\tSave(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"MarkUsageMetricsAsSent: %s\", err)\n\t\treturn fmt.Errorf(\"marking usage metrics as sent: %w\", err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/metrics.go#L40-L76","documentation":"GetBouncerUsageMetricsByName fetches un-pushed metric rows whose GeneratedBy equals the given bouncer name. This error wraps a failing SELECT; it is not raised when the bouncer simply has no metrics (empty slice, nil error).","triggerScenarios":"Calling GetBouncerUsageMetricsByName when the ent query fails: DB locked by a concurrent writer, unreadable/corrupt SQLite file, disk I/O errors, or canceled context.","commonSituations":"cscli/crowdsec contention on the SQLite DB; corrupted DB after power loss; wrong permissions on /var/lib/crowdsec/crowdsec.db after a restore.","solutions":["Read the Warningf log 'GetBouncerUsageMetricsByName: <err>' for the underlying cause.","Fix DB file ownership/permissions or move the DB off NFS.","Run an integrity check and restore the DB if corrupted.","Retry; transient lock contention usually resolves on the next attempt."],"exampleFix":"// before\nm, err := c.GetBouncerUsageMetricsByName(ctx, name)\nif err != nil { return err }\n// after: treat empty as normal, error as fatal\nif err != nil { return fmt.Errorf(\"bouncer metrics: %w\", err) }\nif len(m) == 0 { return nil }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"m, err := client.GetBouncerUsageMetricsByName(ctx, bouncerName)\nif err != nil {\n    return fmt.Errorf(\"bouncer metrics lookup failed: %w\", err)\n}\nif len(m) == 0 { /* bouncer simply has no unpushed metrics */ }","preventionTips":["Handle 'no rows' via empty slice, not error checks.","Keep SQLite on local writable storage.","Integrity-check the DB after unclean shutdowns.","Unwrap the error chain for the driver-level cause before retrying blindly."],"tags":["database","sqlite","query-failure","metrics","bouncers"],"backgroundTag":"database-query-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}