<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym" -->

---
title: Test logging with ReplaceAttr | daily.dev
description: Explains how to use Go's slog.HandlerOptions.ReplaceAttr field to rewrite or drop log attributes before they are emitted. The practical example shows removing...
canonical: https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Test logging with ReplaceAttr | daily.dev
og:description: Explains how to use Go's slog.HandlerOptions.ReplaceAttr field to rewrite or drop log attributes before they are emitted. The practical example shows removing...
og:url: https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym
og:image: https://api.daily.dev/og/posts/m6SVJ81YM.png
og:image:alt: Test logging with ReplaceAttr
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Test logging with ReplaceAttr

**[Boldly Go](https://daily.dev/sources/boldlygo)** · 2 min read · 3 upvotes · 0 comments

## Summary

Explains how to use Go's slog.HandlerOptions.ReplaceAttr field to rewrite or drop log attributes before they are emitted. The practical example shows removing the time attribute so tests can perform exact string matches on log output without being broken by ever-changing timestamps, including sample code for configuring a slog.TextHandler and asserting on the resulting buffer contents.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://boldlygo.tech/archive/2026-09-29-test-logging-with-replaceattr>

## Questions this post answers

### How do I remove the timestamp from Go slog output so I can test log messages with exact string matching?

Use the ReplaceAttr function in slog.HandlerOptions to intercept the time attribute and return a zero slog.Attr, which discards it from the output. Configure a slog.TextHandler with ReplaceAttr checking if a.Key equals slog.TimeKey, returning slog.Attr{} in that case and passing all other attributes through unchanged, producing stable, comparable log strings in tests.

_Developers writing log assertions can track Go slog patterns like this one on daily.dev._

### What does the ReplaceAttr field in Go's slog.HandlerOptions do?

ReplaceAttr is a function called to rewrite each non-group attribute before it is logged, receiving the currently open groups and the resolved Attr. Returning a zero Attr discards that attribute entirely. It also receives the built-in time, level, source, and msg keys, and can be used to rename keys, convert types, sanitize sensitive data, or remove attributes from output.

_daily.dev helps Go developers stay current on slog configuration details like this while building logging pipelines._

## Similar posts on daily.dev

- [slog.Handler.WithAttrs](https://daily.dev/posts/slog-handler-withattrs-l2fs9cp1u) · Boldly Go · 29 upvotes · 1 comments
- [Expanding errors with ReplaceAttr](https://daily.dev/posts/expanding-errors-with-replaceattr-vfxd8vujv) · Boldly Go · 10 upvotes · 1 comments
- [slog Constants](https://daily.dev/posts/slog-constants-sluzy3xoy) · Boldly Go · 20 upvotes · 1 comments
- [The Attr type](https://daily.dev/posts/the-attr-type-udhsolgm5) · Boldly Go · 19 upvotes · 0 comments
- [How to structure a log](https://daily.dev/posts/how-to-structure-a-log-psj5teef9) · Sentry Engineering · 1 upvotes · 0 comments

---

Tags: [#testing](https://daily.dev/tags/testing), [#golang](https://daily.dev/tags/golang)

[View this post on daily.dev](https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Test logging with ReplaceAttr","url":"https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym"},"datePublished":"2026-09-29T20:16:01.570Z","dateModified":"2026-09-29T20:16:21.052Z","description":"Explains how to use Go's slog.HandlerOptions.ReplaceAttr field to rewrite or drop log attributes before they are emitted. The practical example shows removing...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a34bbf94f7c8bcbf828174d099f2faa8?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/a34bbf94f7c8bcbf828174d099f2faa8?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Boldly Go","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Boldly Go","logo":"https://media.daily.dev/image/upload/s--0HXlQZhy--/f_auto,q_auto/v1780213594/logos/boldlygo?_a=BAMAMiWQ0","url":"https://daily.dev/sources/boldlygo"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"testing,golang","timeRequired":"PT2M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Boldly Go","item":"https://daily.dev/sources/boldlygo"},{"@type":"ListItem","position":3,"name":"Test logging with ReplaceAttr"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/test-logging-with-replaceattr-m6svj81ym#faq","mainEntity":[{"@type":"Question","name":"How do I remove the timestamp from Go slog output so I can test log messages with exact string matching?","acceptedAnswer":{"@type":"Answer","text":"Use the ReplaceAttr function in slog.HandlerOptions to intercept the time attribute and return a zero slog.Attr, which discards it from the output. Configure a slog.TextHandler with ReplaceAttr checking if a.Key equals slog.TimeKey, returning slog.Attr{} in that case and passing all other attributes through unchanged, producing stable, comparable log strings in tests. Developers writing log assertions can track Go slog patterns like this one on daily.dev."}},{"@type":"Question","name":"What does the ReplaceAttr field in Go's slog.HandlerOptions do?","acceptedAnswer":{"@type":"Answer","text":"ReplaceAttr is a function called to rewrite each non-group attribute before it is logged, receiving the currently open groups and the resolved Attr. Returning a zero Attr discards that attribute entirely. It also receives the built-in time, level, source, and msg keys, and can be used to rename keys, convert types, sanitize sensitive data, or remove attributes from output. daily.dev helps Go developers stay current on slog configuration details like this while building logging pipelines."}}]}
```

