Start to add zap logger everywhere

This commit is contained in:
Ben Sarmiento
2023-11-05 00:02:22 +01:00
parent 4136310622
commit 1b116c2194
9 changed files with 204 additions and 50 deletions

View File

@@ -3,7 +3,6 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
@@ -11,13 +10,17 @@ import (
"time" "time"
"github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/config"
"github.com/debridmediamanager.com/zurg/internal/mount"
"github.com/debridmediamanager.com/zurg/internal/net" "github.com/debridmediamanager.com/zurg/internal/net"
"github.com/debridmediamanager.com/zurg/internal/torrent" "github.com/debridmediamanager.com/zurg/internal/torrent"
"github.com/debridmediamanager.com/zurg/internal/zfs"
"github.com/debridmediamanager.com/zurg/pkg/logutil"
"github.com/hashicorp/golang-lru/v2/expirable" "github.com/hashicorp/golang-lru/v2/expirable"
) )
func main() { func main() {
rlog := logutil.NewLogger()
log := rlog.Named("main")
config, configErr := config.LoadZurgConfig("./config.yml") config, configErr := config.LoadZurgConfig("./config.yml")
if configErr != nil { if configErr != nil {
log.Panicf("Config failed to load: %v", configErr) log.Panicf("Config failed to load: %v", configErr)
@@ -33,29 +36,52 @@ func main() {
addr := fmt.Sprintf(":%s", config.GetPort()) addr := fmt.Sprintf(":%s", config.GetPort())
server := &http.Server{Addr: addr, Handler: mux} server := &http.Server{Addr: addr, Handler: mux}
mountPoint := config.GetMountPoint()
if _, err := os.Stat(mountPoint); os.IsNotExist(err) {
if err := os.Mkdir(mountPoint, 0755); err != nil {
log.Panicf("Failed to create mount point: %v", err)
}
}
shutdown := make(chan os.Signal, 1) shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM) signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
go func() { go func() {
log.Printf("Starting server on %s\n", addr) defer func() {
if r := recover(); r != nil {
log.Errorf("Server panic: %v\n", r)
}
}()
log.Infof("Starting server on %s\n", addr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Panicf("Failed to start server: %v", err) log.Panicf("Failed to start server: %v", err)
} }
}() }()
// Start the mount in a goroutine. // Start the mount in a goroutine with panic recovery.
go func() { go func() {
if err := mount.Mount(config.GetMountPath()); err != nil { defer func() {
if r := recover(); r != nil {
log.Errorf("Mount panic: %v\n", r)
}
}()
log.Infof("Mounting on %s\n", mountPoint)
if err := zfs.Mount(mountPoint); err != nil {
log.Panicf("Failed to mount: %v", err) log.Panicf("Failed to mount: %v", err)
} }
}() }()
<-shutdown <-shutdown
log.Println("zurg signing off...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
server.Shutdown(ctx) if err := server.Shutdown(ctx); err != nil {
log.Errorf("Server shutdown error: %v\n", err)
}
if err := zfs.Unmount(mountPoint); err != nil {
log.Errorf("Unmount error: %v\n", err)
}
log.Info("Zurg signing off")
} }

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/debridmediamanager.com/zurg/pkg/logutil"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@@ -19,10 +20,14 @@ type ConfigInterface interface {
MeetsConditions(directory, torrentID, torrentName string, fileNames []string) bool MeetsConditions(directory, torrentID, torrentName string, fileNames []string) bool
GetOnLibraryUpdate() string GetOnLibraryUpdate() string
GetNetworkBufferSize() int GetNetworkBufferSize() int
GetMountPath() string GetMountPoint() string
} }
func LoadZurgConfig(filename string) (ConfigInterface, error) { func LoadZurgConfig(filename string) (ConfigInterface, error) {
rlog := logutil.NewLogger()
log := rlog.Named("config")
log.Debug("Loading config file", filename)
content, err := os.ReadFile(filename) content, err := os.ReadFile(filename)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -35,6 +40,7 @@ func LoadZurgConfig(filename string) (ConfigInterface, error) {
switch initialConfig.Version { switch initialConfig.Version {
case "v1": case "v1":
log.Debug("Detected config version: v1")
return loadV1Config(content) return loadV1Config(content)
default: default:

View File

@@ -10,7 +10,7 @@ type ZurgConfig struct {
CanRepair bool `yaml:"enable_repair"` CanRepair bool `yaml:"enable_repair"`
OnLibraryUpdate string `yaml:"on_library_update"` OnLibraryUpdate string `yaml:"on_library_update"`
NetworkBufferSize int `yaml:"network_buffer_size"` NetworkBufferSize int `yaml:"network_buffer_size"`
MountPath string `yaml:"mount_path"` MountPoint string `yaml:"mount_point"`
} }
func (z *ZurgConfig) GetToken() string { func (z *ZurgConfig) GetToken() string {
@@ -57,6 +57,6 @@ func (z *ZurgConfig) GetNetworkBufferSize() int {
return z.NetworkBufferSize return z.NetworkBufferSize
} }
func (z *ZurgConfig) GetMountPath() string { func (z *ZurgConfig) GetMountPoint() string {
return z.MountPath return z.MountPoint
} }

View File

@@ -5,14 +5,19 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/debridmediamanager.com/zurg/pkg/logutil"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
func loadV1Config(content []byte) (*ZurgConfigV1, error) { func loadV1Config(content []byte) (*ZurgConfigV1, error) {
rlog := logutil.NewLogger()
log := rlog.Named("config")
var configV1 ZurgConfigV1 var configV1 ZurgConfigV1
if err := yaml.Unmarshal(content, &configV1); err != nil { if err := yaml.Unmarshal(content, &configV1); err != nil {
return nil, err return nil, err
} }
log.Debug("V1 config loaded successfully")
return &configV1, nil return &configV1, nil
} }
@@ -22,9 +27,13 @@ func (z *ZurgConfigV1) GetVersion() string {
} }
func (z *ZurgConfigV1) GetDirectories() []string { func (z *ZurgConfigV1) GetDirectories() []string {
rlog := logutil.NewLogger()
log := rlog.Named("config")
rootDirectories := make([]string, len(z.Directories)) rootDirectories := make([]string, len(z.Directories))
i := 0 i := 0
for directory := range z.Directories { for directory := range z.Directories {
log.Debug("Adding to rootDirectories", directory)
rootDirectories[i] = directory rootDirectories[i] = directory
i++ i++
} }
@@ -32,6 +41,12 @@ func (z *ZurgConfigV1) GetDirectories() []string {
} }
func (z *ZurgConfigV1) GetGroupMap() map[string][]string { func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
// Obtain a new sugared logger instance
rlog := logutil.NewLogger()
log := rlog.Named("config")
log.Debug("Starting to build the group map from directories")
var groupMap = make(map[string][]string) var groupMap = make(map[string][]string)
var groupOrderMap = make(map[string]int) // To store GroupOrder for each directory var groupOrderMap = make(map[string]int) // To store GroupOrder for each directory
@@ -39,6 +54,7 @@ func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
for directory, val := range z.Directories { for directory, val := range z.Directories {
groupMap[val.Group] = append(groupMap[val.Group], directory) groupMap[val.Group] = append(groupMap[val.Group], directory)
groupOrderMap[directory] = val.GroupOrder groupOrderMap[directory] = val.GroupOrder
log.Debugf("Added directory to group: %s, group: %s, groupOrder: %d", directory, val.Group, val.GroupOrder)
} }
// Sort the slice based on GroupOrder and then directory name for deterministic order // Sort the slice based on GroupOrder and then directory name for deterministic order
@@ -50,6 +66,7 @@ func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
return groupOrderMap[dirs[i]] < groupOrderMap[dirs[j]] return groupOrderMap[dirs[i]] < groupOrderMap[dirs[j]]
}) })
groupMap[group] = dirs groupMap[group] = dirs
log.Debugf("Sorted directories within a group: %s, sortedDirectories: %v", group, dirs)
} }
// Return a deep copy of the map // Return a deep copy of the map

View File

@@ -1,38 +0,0 @@
package mount
import (
"errors"
"log"
"os"
"bazil.org/fuse"
"github.com/mdlayher/sdnotify"
)
func Mount(mountpoint string) error {
n, err := sdnotify.New()
if err != nil && !errors.Is(err, os.ErrNotExist) {
log.Fatalf("failed to open systemd notifier: %v", err)
}
err = n.Notify(
sdnotify.Statusf("service started successfully"),
sdnotify.Ready,
)
if err != nil {
log.Fatalf("failed to send ready notification: %v", err)
}
return Unmount(mountpoint, n)
}
func Unmount(mountpoint string, n *sdnotify.Notifier) error {
log.Println("Unmounting...")
err := n.Notify(
sdnotify.Statusf("service stopped successfully"),
sdnotify.Ready,
)
if err != nil {
log.Fatalf("failed to send stop notification: %v", err)
}
fuse.Unmount(mountpoint)
return nil
}

21
internal/zfs/fs.go Normal file
View File

@@ -0,0 +1,21 @@
package zfs
import (
"os"
"sync"
"bazil.org/fuse/fs"
)
type FS struct {
uid uint32
gid uint32
umask os.FileMode
directIO bool
lock sync.RWMutex
}
// Root returns the root path
func (f *FS) Root() (fs.Node, error) {
return nil, nil
}

45
internal/zfs/mount.go Normal file
View File

@@ -0,0 +1,45 @@
package zfs
import (
"os"
"bazil.org/fuse"
"bazil.org/fuse/fs"
"golang.org/x/sys/unix"
)
func Mount(mountpoint string) error {
options := []fuse.MountOption{
fuse.AllowOther(),
fuse.AllowNonEmptyMount(),
fuse.MaxReadahead(uint32(128 << 10)),
fuse.DefaultPermissions(),
fuse.FSName("zurgfs"),
}
c, err := fuse.Mount(mountpoint, options...)
if err != nil {
return err
}
defer c.Close()
srv := fs.New(c, nil)
filesys := &FS{
uid: uint32(unix.Geteuid()),
gid: uint32(unix.Getegid()),
umask: os.FileMode(0),
}
// Serve our tree via FUSE.
if err := srv.Serve(filesys); err != nil {
return err
}
return nil
}
func Unmount(mountpoint string) error {
fuse.Unmount(mountpoint)
return nil
}

50
internal/zfs/object.go Normal file
View File

@@ -0,0 +1,50 @@
package zfs
import (
"context"
"bazil.org/fuse"
"bazil.org/fuse/fs"
"github.com/debridmediamanager.com/zurg/internal/torrent"
)
type Object struct {
fs *FS
objectID string
}
func (o Object) GetObject() (object *torrent.Torrent, err error) {
return nil, nil
}
func (o Object) Attr(ctx context.Context, attr *fuse.Attr) error {
return nil
}
func (o Object) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
return nil, nil
}
func (o Object) Lookup(ctx context.Context, name string) (fs.Node, error) {
return nil, nil
}
func (o Object) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
return nil
}
func (o Object) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
return nil, nil
}
func (o Object) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
return nil
}
func (o Object) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
return nil, nil
}
func (o Object) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fs.Node) error {
return nil
}

27
pkg/logutil/factory.go Normal file
View File

@@ -0,0 +1,27 @@
package logutil
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func NewLogger() *zap.SugaredLogger {
zapConfig := zap.NewDevelopmentConfig()
zapConfig.EncoderConfig = zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
MessageKey: "msg",
CallerKey: "",
StacktraceKey: "",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalColorLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
}
logger, _ := zapConfig.Build()
defer logger.Sync()
sugar := logger.Sugar()
return sugar
}