4 Provide an `io.Writer` that periodically rotates log files from within the application. Port of [File::RotateLogs](https://metacpan.org/release/File-RotateLogs) from Perl to Go.
6 [![Build Status](https://travis-ci.org/lestrrat-go/file-rotatelogs.png?branch=master)](https://travis-ci.org/lestrrat-go/file-rotatelogs)
8 [![GoDoc](https://godoc.org/github.com/lestrrat-go/file-rotatelogs?status.svg)](https://godoc.org/github.com/lestrrat-go/file-rotatelogs)
18 apachelog "github.com/lestrrat-go/apache-logformat"
19 rotatelogs "github.com/lestrrat-go/file-rotatelogs"
23 mux := http.NewServeMux()
24 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ... })
26 logf, err := rotatelogs.New(
27 "/path/to/access_log.%Y%m%d%H%M",
28 rotatelogs.WithLinkName("/path/to/access_log"),
29 rotatelogs.WithMaxAge(24 * time.Hour),
30 rotatelogs.WithRotationTime(time.Hour),
33 log.Printf("failed to create rotatelogs: %s", err)
37 // Now you must write to logf. apache-logformat library can create
38 // a http.Handler that only writes the approriate logs for the request
39 // to the given handle
40 http.ListenAndServe(":8080", apachelog.CombinedLog.Wrap(mux, logf))
46 When you integrate this to to you app, it automatically write to logs that
47 are rotated from within the app: No more disk-full alerts because you forgot
50 To install, simply issue a `go get`:
53 go get github.com/lestrrat-go/file-rotatelogs
56 It's normally expected that this library is used with some other
57 logging service, such as the built-in `log` library, or loggers
58 such as `github.com/lestrrat-go/apache-logformat`.
63 "github.com/lestrrat-go/file-rotatelogs"
67 rl, _ := rotatelogs.New("/path/to/access_log.%Y%m%d%H%M")
72 log.Printf("Hello, World!")
81 The pattern used to generate actual log file names. You should use patterns
82 using the strftime (3) format. For example:
85 rotatelogs.New("/var/log/myapp/log.%Y%m%d")
88 ## Clock (default: rotatelogs.Local)
90 You may specify an object that implements the roatatelogs.Clock interface.
91 When this option is supplied, it's used to determine the current time to
92 base all of the calculations on. For example, if you want to base your
93 calculations in UTC, you may specify rotatelogs.UTC
97 "/var/log/myapp/log.%Y%m%d",
98 rotatelogs.WithClock(rotatelogs.UTC),
104 This is an alternative to the `WithClock` option. Instead of providing an
105 explicit clock, you can provide a location for you times. We will create
106 a Clock object that produces times in your specified location, and configure
107 the rotatelog to respect it.
109 ## LinkName (default: "")
111 Path where a symlink for the actual log file is placed. This allows you to
112 always check at the same location for log files even if the logs were rotated
116 "/var/log/myapp/log.%Y%m%d",
117 rotatelogs.WithLinkName("/var/log/myapp/current"),
123 $ tail -f /var/log/myapp/current
126 If not provided, no link will be written.
128 ## RotationTime (default: 86400 sec)
130 Interval between file rotation. By default logs are rotated every 86400 seconds.
131 Note: Remember to use time.Duration values.
136 "/var/log/myapp/log.%Y%m%d",
137 rotatelogs.WithRotationTime(time.Hour),
141 ## MaxAge (default: 7 days)
143 Time to wait until old logs are purged. By default no logs are purged, which
144 certainly isn't what you want.
145 Note: Remember to use time.Duration values.
148 // Purge logs older than 1 hour
150 "/var/log/myapp/log.%Y%m%d",
151 rotatelogs.WithMaxAge(time.Hour),
155 ## RotationCount (default: -1)
157 The number of files should be kept. By default, this option is disabled.
159 Note: MaxAge should be disabled by specifing `WithMaxAge(-1)` explicitly.
162 // Purge logs except latest 7 files
164 "/var/log/myapp/log.%Y%m%d",
165 rotatelogs.WithMaxAge(-1),
166 rotatelogs.WithRotationCount(7),
170 ## Handler (default: nil)
172 Sets the event handler to receive event notifications from the RotateLogs
173 object. Currently only supported event type is FiledRotated
177 "/var/log/myapp/log.%Y%m%d",
178 rotatelogs.Handler(rotatelogs.HandlerFunc(func(e Event) {
179 if e.Type() != rotatelogs.FileRotatedEventType {
183 // Do what you want with the data. This is just an idea:
184 storeLogFileToRemoteStorage(e.(*FileRotatedEvent).PreviousFile())
191 Ensure a new file is created every time New() is called. If the base file name
192 already exists, an implicit rotation is performed.
196 "/var/log/myapp/log.%Y%m%d",
197 rotatelogs.ForceNewFile(),
203 Ensure a new file is created every time New() is called. If the base file name
204 already exists, an implicit rotation is performed.
208 "/var/log/myapp/log.%Y%m%d",
209 rotatelogs.ForceNewFile(),
213 # Rotating files forcefully
215 If you want to rotate files forcefully before the actual rotation time has reached,
216 you may use the `Rotate()` method. This method forcefully rotates the logs, but
217 if the generated file name clashes, then a numeric suffix is added so that
218 the new file will forcefully appear on disk.
220 For example, suppose you had a pattern of '%Y.log' with a rotation time of
221 `86400` so that it only gets rotated every year, but for whatever reason you
222 wanted to rotate the logs now, you could install a signal handler to
223 trigger this rotation:
226 rl := rotatelogs.New(...)
228 signal.Notify(ch, syscall.SIGHUP)
230 go func(ch chan os.Signal) {
236 And you will get a log file name in like `2018.log.1`, `2018.log.2`, etc.