Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix log #111

Merged
merged 3 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ require (
golang.org/x/image v0.15.0
google.golang.org/grpc v1.62.1
google.golang.org/protobuf v1.33.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v2 v2.4.0
gorm.io/gorm v1.25.8
Expand All @@ -66,13 +65,19 @@ require (
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jonboulle/clockwork v0.4.0
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lestrrat-go/strftime v1.0.6
)

require (
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
Expand Down
10 changes: 8 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
Expand All @@ -191,6 +193,12 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
Expand Down Expand Up @@ -409,8 +417,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=
Expand Down
20 changes: 20 additions & 0 deletions log/file-rotatelogs/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
The MIT License (MIT)

Copyright (c) 2014 lestrrat

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
237 changes: 237 additions & 0 deletions log/file-rotatelogs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
file-rotatelogs
==================

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.

[![Build Status](https://travis-ci.org/lestrrat-go/file-rotatelogs.png?branch=master)](https://travis-ci.org/lestrrat-go/file-rotatelogs)

[![GoDoc](https://godoc.org/github.com/lestrrat-go/file-rotatelogs?status.svg)](https://godoc.org/github.com/lestrrat-go/file-rotatelogs)

# WARNINGS

THIS PROJECT HAS BEEN ARCHIVED. IT WILL NOT RECEIVE UPDATES, THE AUTHOR DOES NOT WISH TO MAINTAIN OR SUPPORT IT.
IN SHORT, DO NOT USE THIS PROJECT.

# SYNOPSIS

```go
import (
"log"
"net/http"

apachelog "github.com/lestrrat-go/apache-logformat"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
)

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ... })

logf, err := rotatelogs.New(
"/path/to/access_log.%Y%m%d%H%M",
rotatelogs.WithLinkName("/path/to/access_log"),
rotatelogs.WithMaxAge(24 * time.Hour),
rotatelogs.WithRotationTime(time.Hour),
)
if err != nil {
log.Printf("failed to create rotatelogs: %s", err)
return
}

// Now you must write to logf. apache-logformat library can create
// a http.Handler that only writes the approriate logs for the request
// to the given handle
http.ListenAndServe(":8080", apachelog.CombinedLog.Wrap(mux, logf))
}
```

# DESCRIPTION

When you integrate this to into your app, it automatically write to logs that
are rotated from within the app: No more disk-full alerts because you forgot
to setup logrotate!

To install, simply issue a `go get`:

```
go get github.com/lestrrat-go/file-rotatelogs
```

It's normally expected that this library is used with some other
logging service, such as the built-in `log` library, or loggers
such as `github.com/lestrrat-go/apache-logformat`.

```go
import(
"log"
"github.com/lestrrat-go/file-rotatelogs"
)

func main() {
rl, _ := rotatelogs.New("/path/to/access_log.%Y%m%d%H%M")

log.SetOutput(rl)

/* elsewhere ... */
log.Printf("Hello, World!")
}
```

OPTIONS
====

## Pattern (Required)

The pattern used to generate actual log file names. You should use patterns
using the strftime (3) format. For example:

```go
rotatelogs.New("/var/log/myapp/log.%Y%m%d")
```

## Clock (default: rotatelogs.Local)

You may specify an object that implements the roatatelogs.Clock interface.
When this option is supplied, it's used to determine the current time to
base all of the calculations on. For example, if you want to base your
calculations in UTC, you may specify rotatelogs.UTC

```go
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.WithClock(rotatelogs.UTC),
)
```

## Location

This is an alternative to the `WithClock` option. Instead of providing an
explicit clock, you can provide a location for you times. We will create
a Clock object that produces times in your specified location, and configure
the rotatelog to respect it.

## LinkName (default: "")

Path where a symlink for the actual log file is placed. This allows you to
always check at the same location for log files even if the logs were rotated

```go
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.WithLinkName("/var/log/myapp/current"),
)
```

```
// Else where
$ tail -f /var/log/myapp/current
```

Links that share the same parent directory with the main log path will get a
special treatment: namely, linked paths will be *RELATIVE* to the main log file.

| Main log file name | Link name | Linked path |
|---------------------|---------------------|-----------------------|
| /path/to/log.%Y%m%d | /path/to/log | log.YYYYMMDD |
| /path/to/log.%Y%m%d | /path/to/nested/log | ../log.YYYYMMDD |
| /path/to/log.%Y%m%d | /foo/bar/baz/log | /path/to/log.YYYYMMDD |

If not provided, no link will be written.

## RotationTime (default: 86400 sec)

Interval between file rotation. By default logs are rotated every 86400 seconds.
Note: Remember to use time.Duration values.

```go
// Rotate every hour
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.WithRotationTime(time.Hour),
)
```

## MaxAge (default: 7 days)

Time to wait until old logs are purged. By default no logs are purged, which
certainly isn't what you want.
Note: Remember to use time.Duration values.

```go
// Purge logs older than 1 hour
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.WithMaxAge(time.Hour),
)
```

## RotationCount (default: -1)

The number of files should be kept. By default, this option is disabled.

Note: MaxAge should be disabled by specifing `WithMaxAge(-1)` explicitly.

```go
// Purge logs except latest 7 files
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.WithMaxAge(-1),
rotatelogs.WithRotationCount(7),
)
```

## Handler (default: nil)

Sets the event handler to receive event notifications from the RotateLogs
object. Currently only supported event type is FiledRotated

```go
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.WithHandler(rotatelogs.HandlerFunc(func(e rotatelogs.Event) {
if e.Type() != rotatelogs.FileRotatedEventType {
return
}

// Do what you want with the data. This is just an idea:
storeLogFileToRemoteStorage(e.(*rotatelogs.FileRotatedEvent).PreviousFile())
})),
)
```

## ForceNewFile

Ensure a new file is created every time New() is called. If the base file name
already exists, an implicit rotation is performed.

```go
rotatelogs.New(
"/var/log/myapp/log.%Y%m%d",
rotatelogs.ForceNewFile(),
)
```

# Rotating files forcefully

If you want to rotate files forcefully before the actual rotation time has reached,
you may use the `Rotate()` method. This method forcefully rotates the logs, but
if the generated file name clashes, then a numeric suffix is added so that
the new file will forcefully appear on disk.

For example, suppose you had a pattern of '%Y.log' with a rotation time of
`86400` so that it only gets rotated every year, but for whatever reason you
wanted to rotate the logs now, you could install a signal handler to
trigger this rotation:

```go
rl := rotatelogs.New(...)

signal.Notify(ch, syscall.SIGHUP)

go func(ch chan os.Signal) {
<-ch
rl.Rotate()
}()
```

And you will get a log file name in like `2018.log.1`, `2018.log.2`, etc.
17 changes: 17 additions & 0 deletions log/file-rotatelogs/event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package rotatelogs

func (h HandlerFunc) Handle(e Event) {
h(e)
}

func (e *FileRotatedEvent) Type() EventType {
return FileRotatedEventType
}

func (e *FileRotatedEvent) PreviousFile() string {
return e.prev
}

func (e *FileRotatedEvent) CurrentFile() string {
return e.current
}
63 changes: 63 additions & 0 deletions log/file-rotatelogs/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package rotatelogs_test

import (
"fmt"
"io/ioutil"
"os"

rotatelogs "github.com/lestrrat-go/file-rotatelogs"
)

func ExampleForceNewFile() {
logDir, err := ioutil.TempDir("", "rotatelogs_test")
if err != nil {
fmt.Println("could not create log directory ", err)

return
}
logPath := fmt.Sprintf("%s/test.log", logDir)

for i := 0; i < 2; i++ {
writer, err := rotatelogs.New(logPath,
rotatelogs.ForceNewFile(),
)
if err != nil {
fmt.Println("Could not open log file ", err)

return
}

n, err := writer.Write([]byte("test"))
if err != nil || n != 4 {
fmt.Println("Write failed ", err, " number written ", n)

return
}
err = writer.Close()
if err != nil {
fmt.Println("Close failed ", err)

return
}
}

files, err := ioutil.ReadDir(logDir)
if err != nil {
fmt.Println("ReadDir failed ", err)

return
}
for _, file := range files {
fmt.Println(file.Name(), file.Size())
}

err = os.RemoveAll(logDir)
if err != nil {
fmt.Println("RemoveAll failed ", err)

return
}
// OUTPUT:
// test.log 4
// test.log.1 4
}
Loading