From Oodle Skills
Create and manage Oodle log-based metric rules — extract metrics from log streams using filter expressions and groupBy labels.
How this skill is triggered — by the user, by Claude, or both
Slash command
/oodle-agent-skills:oodle-log-metricsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill teaches the agent to convert log streams into metrics safely: validate the filter, narrow the `groupBy`, and avoid creating high-cardinality time series.
This skill teaches the agent to convert log streams into metrics safely: validate the filter, narrow the groupBy, and avoid creating high-cardinality time series.
brew install oodle-ai/oodle/oodle
oodle configure
Confirm the log-metrics endpoint works:
oodle log-metrics list -o json | jq 'length'
Before running any oodle command:
groupBy are already in context.oodle traces list ... or the log explorer) to verify the filter actually matches logs.groupBy count × distinct values per label.oodle log-metrics create -f rule.json only after the filter is validated.update without first running get to capture the existing rule.| Task | Command |
|---|---|
| List rules | oodle log-metrics list -o json |
| Get rule | oodle log-metrics get <id> -o json |
| Create rule | oodle log-metrics create -f rule.json |
| Update rule | oodle log-metrics update <id> -f rule.json |
| Delete rule | oodle log-metrics delete <id> --force |
{
"name": "http_errors_from_logs",
"filter": "level=error AND service=api",
"groupBy": ["service", "env"],
"metricName": "oodle.log.http_errors"
}
Field meaning:
| Field | Meaning |
|---|---|
name | Human identifier for the rule |
filter | Boolean expression over log fields (AND/OR/NOT, =, !=, contains) |
groupBy | Labels promoted from log fields onto the emitted metric |
metricName | The Prometheus-style metric name to emit |
# ✅ CORRECT — validate filter first, then create
# (preview with the log explorer or `oodle traces list` if traces and logs share the same backend)
oodle log-metrics create -f rule.json
# ❌ WRONG — creating with an untested filter; the resulting metric is silently empty
oodle log-metrics create -f <(echo '{"name":"x","filter":"levl=eror","groupBy":[],"metricName":"x"}')
# ✅ CORRECT — get → edit → update
oodle log-metrics get lm_123 -o json > rule.json
jq '.groupBy = ["service","env"]' rule.json > rule.new.json
oodle log-metrics update lm_123 -f rule.new.json
# ❌ WRONG — partial payload removes existing fields
oodle log-metrics update lm_123 -f <(echo '{"groupBy":["service"]}')
# ✅ CORRECT — verify and delete
oodle log-metrics get lm_123 -o json > /dev/null
oodle log-metrics delete lm_123 --force
# ❌ WRONG — speculative delete by name match
oodle log-metrics delete "$(oodle log-metrics list | grep errors | awk '{print $1}')" --force
filter against real log volume before creating the ruleA typo in the filter (levl=eror) creates a rule that silently emits zero data points.
# ✅ CORRECT — preview matching log volume in the log explorer first;
# only then run `oodle log-metrics create`
# (or temporarily create a synthetic monitor that hits the matching logs and confirm count > 0)
# ❌ WRONG — create the rule, then notice the dashboard panel is empty next week
oodle log-metrics create -f rule.json
groupBy to 2–3 low-cardinality labelsEach label multiplies the time-series count. Avoid request_id, user_id, trace_id, path (with IDs).
# ✅ CORRECT — bounded labels
"groupBy": ["service", "env"]
# ❌ WRONG — `user_id` blows up cardinality (one series per user)
"groupBy": ["service", "env", "user_id"]
get before update to preserve fieldsupdate replaces the document. Sending a single field nulls everything else.
# ✅ CORRECT
oodle log-metrics get lm_123 -o json > rule.json
jq '.filter = "level=error AND service=api AND status=5xx"' rule.json > rule.new.json
oodle log-metrics update lm_123 -f rule.new.json
# ❌ WRONG — clobbers groupBy and metricName
oodle log-metrics update lm_123 -f <(echo '{"filter":"level=error"}')
metricNameoodle.log.<domain>.<measurement> makes the metric easy to find in dashboards and drop rules.
# ✅ CORRECT
"metricName": "oodle.log.http_errors"
# ❌ WRONG — generic name collides with other rules
"metricName": "errors"
| Error | Cause | Fix |
|---|---|---|
| 401 Unauthorized | Invalid or missing API key | Run oodle configure or set OODLE_API_KEY |
| 404 Not Found | Log-metric rule ID does not exist | Verify with oodle log-metrics list -o json |
| connection refused | Wrong OODLE_DEPLOYMENT URL | Check OODLE_DEPLOYMENT env var |
invalid filter expression | Filter has a syntax error | Use field=value (no spaces around =); combine with AND/OR/NOT |
| Metric exists but has no data points | Filter doesn't match any logs | Re-test the filter in the log explorer; check label names match the log schema |
| Cardinality alarm in the UI | groupBy includes a high-cardinality field | Edit the rule to drop that field; old series age out at the regular retention |
| 429 Too Many Requests | Bulk rule creation | Add --retries 3, throttle to <10 creates per second |
npx claudepluginhub oodle-ai/agent-skillsProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.