Logrus says it is in maintenance mode, which changes how you should adopt it
Structured, pluggable logging for Go.
At a glance
- What is it?
- The structured logger for Go with a stdlib-compatible API, now focused on security, bug fixes and performance, with the maintainer pointing new projects at zerolog and zap.
- Who is it for?
- The first line to read in Logrus's README is the maintenance-mode notice, and it is unusually direct about the consequence: no new features are planned beyond what interoperability with `log/slog` requires. That is not a criticism of the code, and the recent releases show real work, with v1.10.0 reporting double-digit percentage gains in formatter throughput and allocation reductions, and v1.10.1 and v1.10.2 following with a panic fix and dependency cleanups.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Reading the maintenance mode notice first
The README states it in bold: Logrus is in maintenance mode. The project focuses on security, bug fixes and performance improvements, and new features are not planned aside from changes required for interoperability with other logging ecosystems, with Go's `log/slog` named as the example.
For an existing service this is close to a promise that your dependency will not rot. Bug fixes and security patches are exactly the categories you want from a logging library you are not actively developing. For a new project it is a different signal entirely, because the library you are choosing today is the library you will live with for years and there is no roadmap for new capabilities.
The repository is not archived and the last push was on 2026-08-25, so this is a maintained codebase in the narrow sense. Maintenance mode is a statement about scope, not about abandonment.
Drop-in replacement for the standard library logger
The core claim is API compatibility with the standard library logger. That is a bigger deal than it sounds, because it means adoption is an import-path change:
package main
import log "github.com/sirupsen/logrus"
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
}Replace `log` with `log "github.com/sirupsen/logrus"` across your files and the existing call sites keep compiling while gaining fields. The README also shows the configuration pattern in an `init` function: `SetFormatter`, `SetOutput`, `SetLevel`.
If you need more than one logger, `logrus.New()` returns an instance you can configure independently, and the README notes the attribute-setting API on an instance is slightly different from the package-level exported logger. `logger.Out` takes any `io.Writer`, so writing to a file rather than stderr is a matter of assigning an `*os.File`, with a commented-out `os.OpenFile` example in the README.
Output format depends on whether a terminal is attached
Colour is applied in development when a TTY is attached, and plain text otherwise. The plain-text form is logfmt compatible, which means output written to a file or a pipe can be parsed by the same tooling:
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10The TTY detection is implemented per platform. The tree has separate files for it: `terminal_check_unix.go`, `terminal_check_windows.go`, `terminal_check_bsd.go`, `terminal_check_solaris.go`, plus `terminal_check_appengine.go` and `terminal_check_no_terminal.go` for environments that have neither.
To force plain output even on a terminal, which is what you want in a container whose stdout happens to be a TTY during development, set the formatter explicitly:
logrus.SetFormatter(&logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
})`JSONFormatter` is the other half of the story, aimed at logstash or Splunk:
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}SetReportCaller adds the calling method, at a cost
Caller reporting is one flag:
logrus.SetReportCaller(true)It adds a `method` field holding the calling method, as in a `method=github.com/sirupsen/arcticcreatures.migrate` field in the output.
The README is candid that this is not free. It notes measurable overhead whose cost depends on the Go version, citing between 20 and 40 percent in recent tests with Go 1.6 and 1.7, and points you at `go test -bench=ReportCaller` to validate it in your own environment. Two things follow. Those figures are old, so treat them as an order of magnitude rather than a number to plan around. And turning on caller reporting globally costs you on every log line, including the ones where you never read the field, which is a reasonable argument for enabling it only in the logger instances that need it.
The repository carries several dedicated benchmark files, including `logger_bench_test.go`, `formatter_bench_test.go` and `entry_bench_test.go`, which is what makes those measurements reproducible.
Fields, entries and reusing context across log lines
The idiom the README pushes is `WithFields` with a `logrus.Fields` map rather than interpolated strings, so the key and value survive into the formatter:
logrus.WithFields(logrus.Fields{
"animal": "walrus",
}).Info("A walrus appears")The pattern it highlights for reuse is holding the `logrus.Entry` that `WithFields` returns, then logging through that entry several times so the common fields are attached each time without repeating the map. That is the same shape as the request-scoped logger you would build in any other language, and it is where the structure pays off.
The tree backs up the extensibility story: `hooks.go` and a `hooks/` directory for hooks fired around log events, `entry.go` for the entry type, `formatter.go` with `json_formatter.go` and `text_formatter.go`, and `writer.go`. There are example tests named for custom callers, global hooks, function usage and default field values, which is a decent map of what the API can do.
Performance work in the recent releases
Maintenance mode has not meant neglect of the hot paths. The v1.10.0 release notes report roughly 17 percent lower geomean runtime across the benchmark suite, about 27 percent higher geomean formatter throughput, and between 30 and 44 percent faster common enabled logging paths. Specific calls are named too: `WithError` around 40 percent faster, chained fields around 46 percent faster, and allocation counts down by 25 to 74 percent across measured `TextFormatter` cases, with the largest reductions in coloured output. `JSONFormatter` runtime is described as largely unchanged with small allocation reductions.
The same release covers concurrency correctness and interoperability with modern Go logging APIs, which is the interoperability carve-out from the maintenance-mode notice being used in practice.
The two patches after it are small and specific. v1.10.1 fixed a regression from v1.10.0 where `TextFormatter` could panic when formatting nil or panicking `error` and `fmt.Stringer` values, and allowed function-backed values implementing `error` with `WithError`, `WithField` and `WithFields`. v1.10.2 updated testify to 1.12.1, which removed a legacy `gopkg.in/yaml.v3` entry from the dependency graph, and states there are no functional changes. `go.mod` requires Go 1.23.
What the maintainer says about alternatives
The README makes a case rather than a defence. The maintainer writes that Logrus's biggest contribution was helping to drive the widespread use of structured logging in Go, that there seems to be no reason for a major breaking Logrus V2 since the community built those independently, and that Logrus would look like those alternatives had it been redesigned with what is now known about structured logging in Go.
It then names them: zerolog, zap and apex, with links.
This is worth reading carefully when you are choosing, because it removes the usual ambiguity in a maintenance-mode notice. Nobody is asking you to wait for a roadmap that will never come, and nobody is claiming the existing API is the endpoint of the design. Go's `log/slog`, named in the maintenance-mode paragraph as the interoperability target, is the fourth option and the one already in the standard library.
The import name is also worth a note: the organisation is lower-case, so use `github.com/sirupsen/logrus`. The README calls out that using the capitalised form can cause import conflicts on case-sensitive filesystems.
Editorial conclusion
The first line to read in Logrus's README is the maintenance-mode notice, and it is unusually direct about the consequence: no new features are planned beyond what interoperability with `log/slog` requires. That is not a criticism of the code, and the recent releases show real work, with v1.10.0 reporting double-digit percentage gains in formatter throughput and allocation reductions, and v1.10.1 and v1.10.2 following with a panic fix and dependency cleanups. For an existing codebase with logrus already wired in, staying is the low-risk choice. For a new project, the same README names zerolog, zap and apex as libraries that would look like logrus if it were redesigned today, and Go's own `log/slog` is the other direction to weigh. `go.mod` requires Go 1.23 and the last push was on 2026-08-25.
Frequently asked questions
What is a logrus?
Logrus is a structured logger for Go whose API is completely compatible with the standard library logger, so you can adopt it by changing the import path and keep your existing call sites. It adds log fields as key and value pairs, JSON and logfmt-style output, TTY-aware colouring, hooks and caller reporting. Its README states it is in maintenance mode, with work limited to security, bug fixes, performance and interoperability with Go's log/slog.
How does logrus compare with zap?
Zap is built for speed, allocating far less per log line, and its structured API is the one its own documentation optimises around. Logrus is more conventional, closer to the standard library, and easier to adopt in an existing codebase. The most telling comparison is the maintainer's own: the README says Logrus would look like zap and zerolog if it were redesigned with what is now known about structured logging in Go. Recent logrus releases did cut allocations substantially, so the gap is narrower than it was.
How does logrus compare with zerolog?
Zerolog writes JSON directly and is built around zero-allocation logging, which suits services where logging sits on a hot path. Logrus chooses structured fields with a formatter that switches between coloured text, logfmt and JSON depending on whether a terminal is attached, which is friendlier in development. Zap sits between them on allocation behaviour. Logrus's own README lists zerolog alongside zap and apex as libraries that would resemble it after a redesign.
Should a new Go project use logrus or slog?
For a new project, log/slog has the obvious advantage of being in the standard library with no dependency to adopt or upgrade. Logrus's advantage is a large existing base of familiarity and a drop-in replacement for the standard logger. The maintenance-mode notice is the deciding factor for most new work: logrus will take bug fixes and performance work, but not features. If you pick logrus anyway, the README's own note applies, that its API is what a redesign informed by current Go practice would look like, and that zerolog and zap are the libraries to weigh first.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sirupsen-logrus)