Skills
Skill 19 of 31
Add or improve structured logging in Encore.go using encore.dev/rlog.
3 minutes · 577 words · 8 sections
Install
npx skills add encoredev/skills --skill encore-go-loggingnpx skills add encoredev/skills/plugin marketplace add encoredev/skillsThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
Use encore.dev/rlog for application events that need structured fields or trace integration. Preserve an application’s established field names and event conventions when they are consistent with this guidance.
Add logs for information Encore cannot infer from infrastructure operations:
Encore already traces API requests, database queries, service calls, cache operations, and Pub/Sub activity. Do not narrate that execution with logs such as request started, querying database, or request completed.
Use metrics for aggregate counts and levels. Use traces for call flow and timing. Use logs for the context needed to investigate an individual event.
Keep the message stable and pass alternating string keys and values after it:
import "encore.dev/rlog"
rlog.Info("order rejected",
"event", "order.rejected",
"order_id", orderID,
"product_id", productID,
"reason", "insufficient_inventory",
"requested_quantity", requestedQuantity,
"available_quantity", availableQuantity,
)Avoid interpolating identifiers into the message. Stable messages can be grouped, while fields remain searchable.
For events used by dashboards, alerts, or automation, include a stable event field. Prefer <domain>.<past-tense-event>, such as payment.authorized or subscription.cancelled. Diagnostic logs do not require an event name.
Keep each field name and type consistent across events. Prefer numeric values with explicit units and enum-like values over formatted prose:
rlog.Info("payment authorized",
"event", "payment.authorized",
"amount_minor_units", 14900,
"currency", "SEK",
)Encore’s runtime fields use snake_case. Field names beginning with encore_ are reserved; rlog rewrites them with an x_ prefix.
Encore.go provides Error, Warn, Info, and Debug. It does not expose a Trace function through rlog.
Error: an unexpected failure prevented an operation from completingWarn: the application recovered or continued in a degraded stateInfo: a meaningful, relatively low-volume business eventDebug: diagnostic detail not required for normal operationExpected outcomes such as validation failures, missing resources, rejected logins, or declined payments are not Error events. Use their business meaning to choose a level.
The default minimum level is trace, so all four rlog levels are emitted. Configure log_level in encore.app before adding Debug calls to frequently executed code.
Pass the original error as a field value:
if err := chargeCustomer(ctx, customerID, amount); err != nil {
rlog.Error("payment authorization failed",
"err", err,
"customer_id", customerID,
"amount_minor_units", amount,
"currency", currency,
)
return err
}Passing the error value lets rlog apply its error serialization. Calling err.Error() first passes a plain string.
Log a returned failure at the layer that owns the recovery decision and has the domain context to describe its impact. A lower layer should log only when it handles or suppresses the error, retries, detects an invariant violation, or holds context that the returned error will not contain.
Use rlog.With when several events from one domain operation share fields:
logger := rlog.With("import_id", importID, "tenant_id", tenantID)
logger.Info("user import completed", "succeeded_count", succeededCount, "failed_count", failedCount)
logger.Warn("user import row rejected", "row_number", rowNumber, "reason", "invalid_email")Encore already attaches the service, endpoint, trace ID, and authenticated user ID to request logs. Do not add duplicate copies.
Encore does not redact log fields. Never log credentials, tokens, session identifiers, cookies, authorization headers, secret configuration, payment details, or complete request and response values.
Prefer internal identifiers over personal data. Use a stable non-reversible fingerprint when correlation requires a value that should not be stored.
The sensitive API annotation and encore:"sensitive" struct tag redact request and response payloads from traces; they do not redact values passed to rlog.
Summarize batches and long-running operations with outcomes, counts, and durations. Avoid one log per item unless each failure requires investigation.
Log selected metadata from large values rather than complete provider responses, records, configuration values, slices, or document bodies. Bound previews and review them for sensitive data before logging.
When reviewing an existing application, check loops, Pub/Sub subscribers, middleware, and frequently called helpers first. A small number of these call sites often produces most of the log volume.
See the Encore.go logging guide (opens in a new tab) and rlog package reference (opens in a new tab).
Add or improve structured logging in Encore.go using `encore.dev/rlog`. Covers log placement, levels, stable messages and fields, errors, logging contexts, sensitive data, and log volume.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
main, last pushed 4 September 2026.SKILL.md, not by matching a directory convention. One layout observed: encore/*/SKILL.md.h1 and no skipped levels:.claude-plugin/marketplace.json by Encore, declaring 1 plugin. It is read for editorial metadata only — never as the skill index, which is always the repository tree./encoredev/skills.md, and each skill at its own .md URL.