mirror of
https://github.com/eosswedenorg/thalos
synced 2026-08-16 18:38:13 +02:00
rename app folder to internal.
This commit is contained in:
parent
afb90af1db
commit
9974bfe3fd
28 changed files with 23 additions and 23 deletions
48
internal/log/HookWriter.go
Normal file
48
internal/log/HookWriter.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type HookWriter struct {
|
||||
Writer io.Writer
|
||||
LogLevels []log.Level
|
||||
}
|
||||
|
||||
func (hook *HookWriter) Fire(entry *log.Entry) error {
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = hook.Writer.Write([]byte(line))
|
||||
return err
|
||||
}
|
||||
|
||||
func (hook *HookWriter) Levels() []log.Level {
|
||||
return hook.LogLevels
|
||||
}
|
||||
|
||||
func MakeStdHook(writer io.Writer) *HookWriter {
|
||||
return &HookWriter{
|
||||
Writer: writer,
|
||||
LogLevels: []log.Level{
|
||||
log.InfoLevel,
|
||||
log.DebugLevel,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func MakeErrorHook(writer io.Writer) *HookWriter {
|
||||
return &HookWriter{
|
||||
Writer: writer,
|
||||
LogLevels: []log.Level{
|
||||
log.ErrorLevel,
|
||||
log.WarnLevel,
|
||||
log.FatalLevel,
|
||||
log.PanicLevel,
|
||||
log.TraceLevel,
|
||||
},
|
||||
}
|
||||
}
|
||||
127
internal/log/RotatingFile.go
Normal file
127
internal/log/RotatingFile.go
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Rotating file represents a file that can be rotated when either the file
|
||||
// becomes to large or to old, whatever comes first
|
||||
type RotatingFile struct {
|
||||
fd *os.File
|
||||
size int64
|
||||
maxSize int64
|
||||
ts time.Time
|
||||
maxAge time.Duration
|
||||
format string
|
||||
}
|
||||
|
||||
func open(filename string) (*os.File, error) {
|
||||
return os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0o666)
|
||||
}
|
||||
|
||||
// Open a new rotating file.
|
||||
func NewRotatingFile(filename string, maxSize int64, maxAge time.Duration) (*RotatingFile, error) {
|
||||
if err := os.MkdirAll(path.Dir(filename), 0o766); err != nil && !os.IsExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fd, err := open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stat, err := fd.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &RotatingFile{
|
||||
fd: fd,
|
||||
size: stat.Size(),
|
||||
maxSize: maxSize,
|
||||
ts: time.Now(),
|
||||
maxAge: maxAge,
|
||||
format: "2006-01-02_150405",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Open a new rotating file using a config struct.
|
||||
func NewRotatingFileFromConfig(config Config, suffix string) (*RotatingFile, error) {
|
||||
if len(suffix) > 0 {
|
||||
suffix = "_" + suffix
|
||||
}
|
||||
|
||||
return NewRotatingFile(config.GetFilePath()+suffix+".log", int64(config.MaxFileSize), config.MaxTime)
|
||||
}
|
||||
|
||||
func (w *RotatingFile) newFilename(name string) string {
|
||||
ext := path.Ext(name)
|
||||
if len(ext) > 0 {
|
||||
name = name[:len(name)-len(ext)]
|
||||
}
|
||||
return fmt.Sprintf("%s-%s%s", name, time.Now().Format(w.format), ext)
|
||||
}
|
||||
|
||||
// Get the filename
|
||||
func (w RotatingFile) GetFilename() string {
|
||||
return path.Base(w.fd.Name())
|
||||
}
|
||||
|
||||
// Rotate the file.
|
||||
func (w *RotatingFile) Rotate() error {
|
||||
dst, err := os.OpenFile(w.newFilename(w.fd.Name()), os.O_CREATE|os.O_WRONLY, 0o666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
// Seek to the beginning of file
|
||||
if _, err = w.fd.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// And copy the contents to the new file.
|
||||
if _, err = io.Copy(dst, w.fd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Then truncate the log.
|
||||
if err = w.fd.Truncate(0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.size = 0
|
||||
w.ts = time.Now()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Implement io.Writer interface
|
||||
func (w *RotatingFile) Write(p []byte) (int, error) {
|
||||
n, err := w.fd.Write(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
w.size += int64(n)
|
||||
|
||||
// Check if we should rotate
|
||||
if w.size >= w.maxSize || time.Since(w.ts) >= w.maxAge {
|
||||
if err := w.Rotate(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Implement io.Closer interface
|
||||
func (w *RotatingFile) Close() error {
|
||||
err := w.fd.Close()
|
||||
w.fd = nil
|
||||
return err
|
||||
}
|
||||
35
internal/log/config.go
Normal file
35
internal/log/config.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/eosswedenorg/thalos/internal/types"
|
||||
)
|
||||
|
||||
// Config represents configuration parameters for a log.
|
||||
type Config struct {
|
||||
// Filename where the log is stored.
|
||||
Filename string `yaml:"filename"`
|
||||
|
||||
// Directory where the log files are stored.
|
||||
Directory string `yaml:"directory"`
|
||||
|
||||
// Maximum filesize, the log is rotated when this size is exceeded.
|
||||
MaxFileSize types.Size `yaml:"maxfilesize"`
|
||||
|
||||
// Maximum lifetime of the file before it is rotated.
|
||||
MaxTime time.Duration `yaml:"maxtime"`
|
||||
}
|
||||
|
||||
func (c Config) GetFilename() string {
|
||||
return path.Base(c.Filename)
|
||||
}
|
||||
|
||||
func (c Config) GetDirectory() string {
|
||||
return path.Clean(c.Directory)
|
||||
}
|
||||
|
||||
func (c Config) GetFilePath() string {
|
||||
return path.Join(c.GetDirectory(), c.GetFilename())
|
||||
}
|
||||
84
internal/log/config_test.go
Normal file
84
internal/log/config_test.go
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfig_GetDirectory(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
directory string
|
||||
want string
|
||||
}{
|
||||
{"empty", "", "."},
|
||||
{"root", "/", "/"},
|
||||
{"one", "dir", "dir"},
|
||||
{"path", "/path/to/some/directory", "/path/to/some/directory"},
|
||||
{"relative", "relative/directory", "relative/directory"},
|
||||
{"backtrace", "/path/./to/some/../directory", "/path/to/directory"},
|
||||
{"multislash", "//path/to///directory//", "/path/to/directory"},
|
||||
{"everything", "path/to/..//./from/directory//", "path/from/directory"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := Config{
|
||||
Directory: tt.directory,
|
||||
}
|
||||
if got := c.GetDirectory(); got != tt.want {
|
||||
t.Errorf("Config.GetDirectory() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_GetFilename(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filename string
|
||||
want string
|
||||
}{
|
||||
{"empty", "", "."},
|
||||
{"name", "some_file.txt", "some_file.txt"},
|
||||
{"path", "/path/to/my.log", "my.log"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := Config{
|
||||
Filename: tt.filename,
|
||||
}
|
||||
if got := c.GetFilename(); got != tt.want {
|
||||
t.Errorf("Config.GetFilename() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_GetFilePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filename string
|
||||
directory string
|
||||
want string
|
||||
}{
|
||||
{"empty", "", "", "."},
|
||||
{"directory", "", "dir", "dir"},
|
||||
{"filename", "filename", "", "filename"},
|
||||
{"both", "filename", "dir", "dir/filename"},
|
||||
{"root", "filename", "/", "/filename"},
|
||||
{"abs", "filename", "/path/to/logs", "/path/to/logs/filename"},
|
||||
{"relative", "filename", "/srv/../log", "/log/filename"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := Config{
|
||||
Filename: tt.filename,
|
||||
Directory: tt.directory,
|
||||
}
|
||||
if got := c.GetFilePath(); got != tt.want {
|
||||
t.Errorf("Config.GetFilePath() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
15
internal/log/init.go
Normal file
15
internal/log/init.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Initialize logger
|
||||
formatter := log.TextFormatter{
|
||||
FullTimestamp: true,
|
||||
TimestampFormat: "2006-01-02 15:04:05.0000",
|
||||
}
|
||||
|
||||
log.SetFormatter(&formatter)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue